浅析反向代理

最近这段时间频频接触到反代的东西,所以就更进一步的了解了一番, 有什么不对的地方还请大佬们指正~
本文需要用到的代码已上传Github
本文由安全客原创发布

本文涉及到的东西仅供技术研究,请勿用于非法用途,否则后果自负

浅析反向代理

0x01: 前言

最近把博客重新弄了一下,发现了一个特别有意思的东西,看图~
Alt text

还有一些有意思的东西,比如反代谷歌(谷歌镜像站)、钓鱼、绕过国内备案和线下CTF中的一些骚操作,等等。

0x02: 简介

反向代理,简而言之就是反向代理服务器从目标内容服务器上抓取内容返回给用户,反向代理服务器充当一个中介功能,他本身是没有任何内容的。区别于正向代理而言,反向代理是代理的服务端,而正向代理是代理的客户端。
Alt text

再来简单介绍一下我在前言中所说的我让我的博客ip是如何变成1.1.1.1的,其实1.1.1.1是一台DNS服务器(号称全球最快的DNS),正好1.1.1.1又是cf cdn中的一个节点。这样我们就可以将域名解析到1.1.1.1,然后在cf中设置好真实的回源地址即可。在文末已附上教程链接,感兴趣的可以玩玩~

0x03: 一些有意思的东西

除了上述所说的套一个CDN,让自己ip变成1.1.1.1来隐藏自己站点ip,还有一些其他好玩的~

  1. CTF线下中的一些思路
    因为我们线下赛中每支队伍的web站点都一样,笔者在之前的一次线下训练赛的时候尝试过修改apache配置文件来反代分数最高的队伍的站点,从而达到流量转发(伤害转移)的效果。这个具体能不能实现得看服务器的权限能提升到多高,其次也得根据具体的check机制来灵活使用。如果提升的权限不够高的话,也可以配置.htaccess来实现反代。用tcpdump倒流量顺手抓一波别人的payload。
    如果我们采用的是.htaccess方法进行反向代理,这里说一下这种方法的原理和其他的不同在于它本质上是利用.htaccess映射到一个php文件,然后利用php文件去抓取目标服务器的信息返回给客户端。这里.htaccess配置的作用是重写url。所以我们不妨在这个php文件中包含一下这个demo1.php即可达到payload的记录的效果:

代码如下:
demo1.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
write_log();

function get_http_raw() {
$raw = '';

$raw .= $_SERVER['REQUEST_METHOD'].' '.$_SERVER['REQUEST_URI'].' '.$_SERVER['SERVER_PROTOCOL']."\r\n";

foreach($_SERVER as $key => $value) {
if(substr($key, 0, 5) === 'HTTP_') {
$key = substr($key, 5);
$key = str_replace('_', '-', $key);
$raw .= $key.': '.$value."\r\n";
}
}
$raw .= "\r\n";
$raw .= file_get_contents('php://input');
return $raw;
}


function write_log(){
$data = date("Y/m/d H:i:s")."\r\n".get_http_raw()."\r\n\r\n";
$file = fopen('log1.txt', 'a'); //日志路径
fwrite($file, $data);
fclose($file);

}

记录如下:
Alt text

  1. 克隆网站 –中间人攻击
    我们可以安装一个nginx的第三方模块ngx_http_substitutions_filter_module,然后nginx的配置文件中加入一段,即可弹窗等。
1
subs_filter </head> "<script>alert('1');</script></head>";

location部分的配置如下:
Alt text

这里有个坑弄了我好久… 就是我们请求网站的时候,数据包头部一般会有Accept-Encoding部分,如下图所示,这个部分告诉服务器,客户端能以怎样的形式解码。那么问题来了,数据包是压缩的,我们怎样才能用subs_filter 替换其中的内容呢? 其实正像上面截图的配置那样设置:反代服务器请求上游服务器的时候带上Accept-Encoding=‘ ’ 即可,表示不接受任何压缩数据。

Alt text

访问https://a.cuit.store,效果如下:
Alt text

这样如果我们反代一个登录页面,比如qq空间,然后植入我们的js脚本,后果emmm…
当然了,不同站的反代难度是不一样的~

  1. 绕过网站所有权验证,调用在线的云扫描器给我们需要渗透的网站进行扫描
    以人人扫这个云扫描平台为例:https://www.renrenscan.com/, 其中需要我们把一个认证文件放到网站根目录上,我们可以设置反代规则的时候,对这个文件进行排除,不进行代理即可绕过,或者直接用.htaccess的方法进行反代就行。
    Alt text
    这样我们只需要等待扫描结果,即可get目标站的漏洞了~

如果我们再邪恶一点….顺便也可以包含上demo1.php,把这些扫描的payload都导出来下来(手动滑稽)

ps:这里说点其他的,我发现在给我博客加cdn的时候,发现了如下图所示的这个,因为我用的是cloudflare免费版的套餐,可以看到有很多请求没有经过CDN处理就直接回源了,这就可以让我们想到如果我们渗透的站点是套了CDN的,常规的找邮件服务器,静态文件,ssrf啥的如果都不管用,还不如来点简单粗暴的,暴力发包让CDN承受不住而回源,这样真实ip’轻松’get~

Alt text

0x04: 反向代理不当

一般当我们遇到了反代服务器的时候,可以试着用burpsuite的repeat功能,设置host为反代服务器,然后把http请求中的路径改为内网中的host(一般需要穷举,穷举网段ip端口域名等等)。因为反向代理的本质就是将客户端的请求url重写后发往上游服务器,将返回结果发回客户端,在这之中,如果对路径的配置不当就有可能导致反向代理变正向代理导致一些信息泄露,内网穿透等等漏洞。
Alt text

参考:
陌陌web服务器Path处理不当可以正向代理
内网穿透代理洞
谷歌内部主机信息泄露漏洞
新浪HTTP代理配置不当漫游内网
挖洞经验之代理不当日进内网

还有一种就是nginx为Django做反代的时候,静态文件配置错误导致源码泄露

##0x05: 如何防止被反向代理
反向代理不仅会对用户造成威胁,而且对服务器来说也会增强负载,还有就是通过代理的方式盗取网站数据,还有就是seo相关的影响了等等…

  1. 通过js防止反代:如果地址栏的网址不是www.passer6y.fun那么就进行跳转。
    1
    2
    3
    4
    5
    <script type="text/javascript">
    if (document.domain !='www.passer6y.fun'){
    window.location.href='https://www.passer6y.fun/';
    }
    </script>

其实这种方法还是可以绕过的,nginx有扩展模块可以将指定的字符进行替换,这时我们只需将target域名替换成我们自己的就行了(上文有说到如何替换)。或者直接不代理这个js文件也行。

  1. php

    1
    2
    3
    4
    5
    6
    <?php 
    if($_SERVER['SERVER_NAME'] != 'www.passer6y.fun' )
    {
    header('Location: https://www.passer6y.fun/');
    }
    ?>
  2. .htaccess

.htaccess

1
2
3
RewriteEngine On
RewriteBase /
php_value auto_append_file proxy.php

proxy.php

1
2
3
4
5
6
7
8
<?php
$f = getenv(“HTTP_X_FORWARDED_FOR”);
$server = getenv(“HTTP_HOST”);
if (($f!=””)&&($server!=”www.passer6y.fun”){
echo ‘本服务器禁止恶意反向代理!’;
}

?>

0x06: Apache 反代配置方法

1. windows下:

修改配置文件:Apache\conf\httpd.conf,将以下两个前面的注释符去掉。

1
2
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_http_module modules/mod_proxy_http.so

然后新增一个Apache\conf\vhosts.conf文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<VirtualHost *:80>

ServerAdmin admin # 域名信息

ServerName passer6y.cn # 邮件信息

ProxyRequests Off

<Proxy *>

Order deny,allow

Allow from all

</Proxy>

ProxyPass / https://passer6y.cn/ # 将一个远端服务器映射到本地服务器的URL空间

ProxyPassReverse / https://passer6y.cn/ # 调整由反向代理服务器发送的HTTP回应头中的URL。

</VirtualHost>

2. linux下

参考:https://www.leaseweb.com/labs/2014/12/tutorial-apache-2-4-transparent-reverse-proxy/
测试环境:Ubuntu 16.04,apache2
加载”proxy_http”模块:

1
2
sudo a2enmod proxy_http
sudo service apache2 restart

在/etc/apache2/sites-available/下,修改配置:

1
2
3
4
5
6
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / https://192.168.83.1/ # 指定根URL(/)下的内容映射到给定地址的后端服务器
ProxyPassReverse / https://192.168.83.1/
</VirtualHost>
~

重启apache生效配置:

1
2
sudo service apache2 reload
sudo service apache2 restart

3. .htaccess配置反向代理

这种方法配置反向代理准确的说是php反向代理,我们通过.htaccess中配置一些重写规则,然后把请求映射到一个php文件中,这个php帮我们请求上游服务器的内容,然后将上游服务器的返回的内容获取回来发回客户端。这种配置反代的好处是所需权限比较小,但是也有很多弊端,随着网站的复杂度,我们所写的抓取页面的php脚本难度就不大一样了。

Github上放了3个php反代脚本的demo,使用说明也见里面的readme即可。

##0x07 nginx 反向代理

1. 简单反代

Nginx核心配置文件nginx.conf:

1
2
3
4
5
6
7
8
9
 server {
listen 80; # 监听端口(web服务端口)
server_name localhost; # 当前服务的域名,这里是本地测试

location / { # 这里的/ 表示把服务器的根目录反代到www.baidu.com的根目录。
proxy_pass https://www.baidu.com;
proxy_redirect default;
}
}

2. 实例:反代Google

测试环境:cent os7
条件准备:一个域名,OneinStack一键安装lnmpLet’s Encrypt 的ssl证书

接下来编辑nginx下的主机配置文件:/usr/local/nginx/conf/vhost/
Alt text
然后在最后插入:

1
2
3
4
5
6
7
location / {  
proxy_set_header Host "www.google.com";
proxy_set_header User-Agent $http_user_agent;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_pass https://www.google.com;
}

检测Nginx配置是否正确:

1
2
3
[root@vultr vhost]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

重载Nginx服务:

1
2
[root@vultr vhost]# service nginx reload
Reloading nginx configuration (via systemctl): [ OK ]

打开google.cuit.store,成功~

0x08 结语

这次介绍了我所了解的三种反代情况以及其中一些有意思的玩法。笔者能力有限,第一次写文章有什么理解不对的地方还请大家多多指点!