0x00 引言
在一套完整的攻击流程中,反弹Shell是非常关键的一步,攻击者可以借此获取受害机器的文件系统控制权。本文介绍常见的几种反弹Shell方法,以及提供一些简单的检测反弹的思路。
0x01 基础知识
在开始之前需要先理解什么是反弹Shell,以及学会如何甄别受害机器的特征。
1 | 1 反弹Shell流程 |
1、反弹Shell流程
假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面、web服务、ssh、telnet等等都是正向连接。但是在某些情况下,正向连接可能会被阻止,比如防火墙屏蔽。为了解决这个问题,便衍生出了反弹Shell的方法。
反弹Shell,即攻击者指定服务端并开启某端口监听,受害者主机主动连接攻击者的服务端程序。
2、文件描述符
linux文件描述符可以理解为linux跟踪打开文件而分配的一个数字句柄,这个数字本质上是一个文件句柄,通过句柄就可以实现文件的读写操作。进程启动后再打开新的文件,描述符会自动依次增加。每一个新进程都会继承其父进程的文件描述符,因此所有的shell命令(本质上也是启动新进程),都会默认有三个文件描述符,即标准输入、标准输出、标准错误输出符号。查看文件描述符的方法是:
1 | $ ll /proc/'进程PID'/fd |
0代表标准输入,1代表标准输出,2代表标准错误输出。默认情况下其都指向/dev/pts/1这个设备(/dev/tty/0代表终端0,/dev/pts/1代表远程终端1,具体区别查看文献[1])。
3、重定向
Linux支持将标准的输入输出重新指定到其他文件、socket号或者pipe管道上,这里介绍如何进行文件描述符重定向:
1 | # 输入重定向 - < |
4、查看受害机器的连接状态
1 | # 定位测试的可疑进程PID |
0x02 常见方法
在以下方法[2]中,攻击端大部分均使用nc工具开启端口监听(特殊的攻击端会在特定方法中描述):
1 | # -l 监听模式 |
且在一个正常的nc服务运行流程中,客户端终端的标准输入输出应该是不会被篡改的,其流程图如下:
1 | 1 内置命令 |
1、内置命令
以下几种方法使用Linux内置命令,不需要另外安装工具。
1.1、bash直接重定向
1 | # 受害机器执行命令 |
使用bash是最简单直接的反弹Shell方法,其原理是将一个终端进程的标准输入输出以及标准错误输出全部重定向到某个socket连接上,实现流程图如下:
1.2、exec添加描述符重定向
1 | # 受害机器执行命令 |
exec命令可以指定一个大于3的文件描述符作为文件的句柄,由于重定向了标准输入输出到大于3的描述符,因此会多产生一个255的文件描述符(在不同终端内,该描述符数字不同)。while read line句式[3]能逐行读取输出并将其赋值给line变量,继而在do done内部实现对变量的操作,下面详细分析实现原理:
1 | # 将远程连接socket的句柄用文件描述符5来表示 |
1.3、管道文件
1 | # 受害机器执行命令 |
mknod命令能够新建一个管道,上述新建了一个名为backpipe的管道文件。nc与bash均为常驻进程,两个进程间使用匿名管道’|’连接。最终实现了一个单向循环,下面详细分析实现原理:
1 | # 新建一个管道文件backpipe |
1.4、匿名双管道
由于匿名双管道方法的特殊性,攻击端的监听命令需要改变为如下:
1 | # 监听命令 |
其原理较为简单, 执行流程图如下:
2、第三方工具
使用第三方工具,实际上与内置工具大同小异,其实际的实现方法与上述类似,这边罗列几个典型的工具。
2.1、nc
1 | # 受害机器执行命令 |
2.2、socat
1 | # 监听命令 |
这工具按ctrl+c不会断开连接,而且通过文件描述符比较难辨别,暂时不知道如何探测。
2.3、python
1 | # 受害机器执行命令 |
此种方法使用os的subprocess在本地开启一个子进程,启动bash交互模式,标准输入、标准输出、标准错误输出被重定向到了远程。实质就是Bash直接重定向。
0x03 检测思路
1 | 1 旧的检测方案及其误报原因 |
1、旧的检测方案及其误报原因
旧的检测方案为检查所有进程的文件描述符,一旦其socket连接号能够在/proc/net/tcp中找到对应的远程连接IP,则会上报反弹Shell攻击。找到两台机器,其误报进程信息如下:
1 | # 误报案例一 |
容易分析,误报原因为标准输入未被劫持,但是标准输出与标准错误输出被劫持,反弹Shell未形成一条链。
2、方案改进