应用frp+Nginx绕过WAF对部署在公有云上的网站进行安全测试

免责声明

        本文所提供的程序(方法)可能带有攻击性,仅供安全研究与教学之用。文章作者无法鉴别判断读者使用信息及工具的真实用途,若读者将文章中的工具或信息做其他用途,由读者承担全部法律及连带责任,segmentfault和本文作者不承担任何法律及连带责任。

相关资料

frp下载 :frp

Nginx下载 :Nginx

背景介绍

        应甲方要求,对其某个业务系统进行授权渗透测试。

        该系统部署在阿X云,系统前端部署在代理主机,后端部署在应用主机。应用主机与代理主机使用内网连接,采用http协议,不对互联网暴露。

        通过互联网访问目标系统时,域名解析指向代理主机,代理主机部署了Nginx对请求的子域名进行正向代理,以满足将来扩充业务的需求。

        网络拓扑示意图如下:

应用frp+Nginx绕过WAF对部署在公有云上的网站进行安全测试_第1张图片       
果然,在随后的渗透测试过程中,遭遇到阿X云WAF的拦截,请求包被RESET。在尝试上传任意文件后缀名为jsp、php时,更是遭遇到IP临时封禁的专属服务。后与甲方沟通多次,表示不能提供打包镜像或者本地测试环境。

解决思路       

        转而求其次,向甲方申请在云主机上部署FRP,建立加密隧道,来绕过WAF对渗透测试的干扰。

        甲方对该方案表示认可,但要求必须保证隧道安全。于是我决定采用FRP内置的STCP协议对TCP隧道进行加密传输,还有一个好处是可以确保报文内容不会被WAF检测。

       在部署之前对业务流程进行了更深入的考虑:代理主机和应用主机之间也采用了http协议通信,只将FRP部署在代理主机,从代理主机到应用主机的报文是未加密的。如果此时通过安全隧道从代理主机向应用主机进行渗透测试,则会触发内部网络的WAF动作,极端情况下会导致代理主机的内网IP遭到封禁,使业务中断。

        最终解决方案是在代理主机和应用主机分别部署FRP,代理主机和应用主机在防火墙的同一个安全组内,开启TCP10000/10000,指定IP为88.88.88.88。

        添加过FRP后的网络拓扑示意图如下:

应用frp+Nginx绕过WAF对部署在公有云上的网站进行安全测试_第2张图片

测试主机通过FRPS建立和两台云主机的安全隧道,再将安全隧道与本地端口进行绑定。这里绑定了8010端口和8020端口,此时在浏览器访问127.0.0.1:8010和127.0.0.1:8020,均顺利返回了相应的静态资源,证明隧道成功建立。

        接下来要对测试主机的80端口复用,这时候就用到了最著名的代理软件——Nginx

       (在这里当时第一时间想到的工具不是Nginx,而是Windows自带的netsh.exe。使用portproxy命令可以实现端口转发,直接将80端口转发到对应的本地端口,但是由于Hosts文件只关注网络层的转换,所以无法完成对80端口的复用。端口复用需要工作在传输层的软件才能完成,于是顺理成章的想到了Nginx。)

       首先修改Hosts文件,将所有与测试有关的域名都指向127.0.0.1。这里注意不能采用模糊匹配,一定要精确匹配到子域名。

       然后在测试主机本地搭建Nginx作为正向代理,监听来自本机80端口的http请求。修改Nginx的配置文件,使得不同的域名请求转发到对应的本地端口。

       最后再由FRPC将监听的本地端口报文以安全TCP协议(STCP)传输到相应的云主机。

        测试主机访问的整个流程示意图如下:

应用frp+Nginx绕过WAF对部署在公有云上的网站进行安全测试_第3张图片

        测试过程中需要使用到Burp进行抓包,将Burp监听端口设为8090,浏览器代理指向127.0.0.1:8090即可实现。

应用frp+Nginx绕过WAF对部署在公有云上的网站进行安全测试_第4张图片

        使用Burp抓包后,测试域名已经指向本地。

       使用多种工具进行测试后均无异常,成功绕过WAF,开始一展身手吧!

配置步骤

安装并配置FRPS

        登录具有公网IP的主机,这里我购买了一台阿X云轻量应用服务器,下载FRP:

wget https://github.com/fatedier/frp/releases/download/v0.20.0/frp_0.20.0_linux_386.tar.gz

下载完成后进行解压缩:

tar -zxvf frp_0.20.0_linux_386.tar.gz

配置FRPS

        进入frp_0.20.0_linux_386,修改 frps.ini 文件,这里给出一个最基础的配置,需要更多功能请参阅官方文档:

[common]
bind_addr = 0.0.0.0
bind_port = 10000
token = 这里是密码,复杂度越高越好  

其中

“bind_port”为FRPS与FRPC通信的端口,配置后需要在阿X云防火墙添加对应规则。

“token”为连接FRPS时所需要的口令,建议复杂度越高越好。

启动FRPS

nohup ./frps -c ./frps.ini &  

查看运行状态

tail -f nohup.out  

安装并配置云主机端FRPC

        登录相应主机,下载解压FRP:

wget https://github.com/fatedier/frp/releases/download/v0.20.0/frp_0.20.0_linux_386.tar.gz
tar -zxvf frp_0.20.0_linux_386.tar.gz

配置代理主机FRPC

        进入frp_0.20.0_linux_386,修改 frpc.ini 文件,这里给出一个最基础的配置,需要更多功能请参阅官方文档:

[common]
server_addr = 88.88.88.88
server_port = 10000
token = 密码与FRPS相同
protocol = tcp
login_fail_exit = false
user = web01
[Web8010]
type = stcp
sk = 设定连接8010端口的口令
local_ip = 127.0.0.1
local_port = 8010
[Web8020]
type = stcp
sk = 设定连接8020端口的口令
local_ip = 127.0.0.1
local_port = 8020  

其中

“server_addr”为FRPS的IP地址。

“server_port”为FRPC与FRPS通信的端口。

“token”为连接FRPS时所需要的口令。

“user”为当前FRPC用户身份,具有唯一性。

“[Web8010]”为一个安全隧道的名称,具有唯一性。

“sk”为连接当前安全隧道所需要的口令,建议复杂度越高越好。

“local_ip”为安全隧道监听的云主机IP,这里填写本机。

“local_port”为安全隧道监听的云主机端口,这里监听了8010和8020端口。

启动FRPC

nohup ./frpc -c ./frpc.ini &

查看运行状态

tail -f nohup.out

配置应用主机FRPC

        进入frp_0.20.0_linux_386,修改 frpc.ini 文件,这里给出一个最基础的配置,需要更多功能请参阅官方文档:

[common]
server_addr = 88.88.88.88
server_port = 10000
token = 密码与FRPS相同
protocol = tcp
login_fail_exit = false
user = web02
[Web8080]
type = stcp
sk = 设定连接8080端口的口令
local_ip = 127.0.0.1
local_port = 8080  

其中

“user”为当前FRPC用户身份,具有唯一性。

“[Web8080]”为一个安全隧道的名称,具有唯一性。

“sk”为连接当前安全隧道所需要的口令,建议复杂度越高越好。

“local_ip”为安全隧道监听的云主机IP,这里填写本机。

“local_port”为安全隧道监听的云主机端口,这里监听了8010和8020端口。

启动FRPC

nohup ./frpc -c ./frpc.ini &

查看运行状态

tail -f nohup.out

  

安装并配置测试终端FRPC

        测试终端使用Windows系统,需要下载Windows版FRP:

Frp_0.20.0_windows_amd64.zip

配置测试终端FRPC

        进入frp_0.20.0_windows_amd64,修改 frpc.ini 文件,这里给出一个最基础的配置,需要更多功能请参阅官方文档:

[common]
server_addr = 88.88.88.88
server_port = 10000
token = 密码与FRPS相同
protocol = tcp
user = TEST1
[Web8010_visitor]
role = visitor
type = stcp
server_name = web01.Web8010
sk = 与连接代理主机8010端口的口令相同
bind_addr = 127.0.0.1
bind_port = 8010
[Web8020_visitor]
role = visitor
type = stcp
server_name = web01.Web8020
sk = 与连接代理主机8020端口的口令相同
bind_addr = 127.0.0.1
bind_port = 8020
[Web8080_visitor]
role = visitor
type = stcp
server_name = web02.Web8080
sk = 与连接应用主机8080端口的口令相同
bind_addr = 127.0.0.1
bind_port = 8080

其中

“server_addr”为FRPS的IP地址。

“server_port”为FRPC与FRPS通信的端口。

“token”为连接FRPS时所需要的口令。

“user”为当前FRPC用户身份,具有唯一性。

“[Web8010_visitor]”为一个安全隧道访客的名称,具有唯一性。

“server_name”为访问的安全隧道,具体格式为:FRPC用户.安全隧道名称。

“sk”为连接当前安全隧道所需要的口令。

“bind_addr”为安全隧道转发的目的IP地址,这里填写本机。

“bind_port”为安全隧道转发的端口号。

启动FRPC

        运行CMD.exe,切换到当前目录,输入:

frpc -c frpc.ini

        至此,使用浏览器访问http://127.0.0.1:8010和http://127.0.0.1:8020已经可以成功请求到代理主机上的静态资源。

修改测试终端Hosts文件

        打开Hosts文件,路径为“C:\Windows\System32\drivers\etc\hosts”,添加内容:

127.0.0.1 a.test.com
127.0.0.1 b.test.com
127.0.0.1 c.test.com

        保存后关闭。

安装并配置测试终端Nginx

        测试终端使用Windows系统,需要下载Windows版Nginx

        下载完成后,进入nginx-1.18.0\conf\,打开nginx.conf文件进行配置。

        这里给出一个最基础的配置,需要更多功能请参阅官方文档:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

#8010
server {
        listen       80; 
        server_name  a.test.com;
         location / { 
         proxy_pass http://127.0.0.1:8010;
         }   
         error_page   500 502 503 504  /50x.html;
            location = /50x.html {
         root   html;
         }   
      }   


#8020
server {
        listen       80; 
         server\_name  b.test.com;
         location / { 
         proxy\_pass http://127.0.0.1:8020;
         }   
         error\_page   500 502 503 504  /50x.html;
         location = /50x.html {
         root   html;
         }   
      }


#8080
server {
        listen       80; 
         server\_name  c.test.com;
         location / { 
         proxy\_pass http://127.0.0.1:8080;
         }   
         error\_page   500 502 503 504  /50x.html;
         location = /50x.html {
         root   html;
         }   
      }

}

启动Nginx

        切换到nginx-1.18.0目录,双击Nginx.exe,打开任务管理器,如果出现Nginx.exe则启动成功。

此时访问http://a.test.com、http://b.test.com、http://c.test.com,均指向了本地的对应端口。

你可能感兴趣的:(frp,nginx,burpsuite)