免责声明
本文所提供的程序(方法)可能带有攻击性,仅供安全研究与教学之用。文章作者无法鉴别判断读者使用信息及工具的真实用途,若读者将文章中的工具或信息做其他用途,由读者承担全部法律及连带责任,segmentfault和本文作者不承担任何法律及连带责任。
相关资料
frp下载 :frp
Nginx下载 :Nginx
背景介绍
应甲方要求,对其某个业务系统进行授权渗透测试。
该系统部署在阿X云,系统前端部署在代理主机,后端部署在应用主机。应用主机与代理主机使用内网连接,采用http协议,不对互联网暴露。
通过互联网访问目标系统时,域名解析指向代理主机,代理主机部署了Nginx对请求的子域名进行正向代理,以满足将来扩充业务的需求。
网络拓扑示意图如下:
果然,在随后的渗透测试过程中,遭遇到阿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后的网络拓扑示意图如下:
测试主机通过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)传输到相应的云主机。
测试主机访问的整个流程示意图如下:
测试过程中需要使用到Burp进行抓包,将Burp监听端口设为8090,浏览器代理指向127.0.0.1:8090即可实现。
使用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:
配置测试终端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则启动成功。