CVE-2020-26217&CVE-2020-26259 Xstream远程代码执行任意文件删除漏洞分析
影响范围
Xstream <= 1.4.14
CVE-2020-26217
漏洞复现
poc:
1 | <map> |
漏洞分析
首先我们将xml文件折叠一下
entry元素中包含了jdk.nashorn.internal.objects.NativeString与string两个元素
这里使用先知社区熊本熊本熊师傅的文章里的例子
map里面put的键为一个对象,值为字符串,那么输出结果就如上,这样也就懂了poc的结构,也就是是一个key为jdk.nashorn.internal.objects.NativeString,value为test的一个entry,而jdk.nashorn.internal.objects.NativeString对象又存在flags、value属性,它的flags属性值为0、value属性值为com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data
接下来开始分析漏洞触发流程
下断点跟进,Xstream解析map结构时会在putCurrentEntryIntoMap中新建一个map,然后将键值取出put进去
这里有一个map的原理,map在put key操作时需要获取key的hash值。因此程序调用了jdk.nashorn.internal.objects.NativeString的hashCode方法
跟进getStringValue方法
这里会判断this.value是不是String实例,如果不是则调用this.value的toString方法
这里的value其实就是
1 | <jdk.nashorn.internal.objects.NativeString> |
这里的value,也就是com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data,所以也就是调用了Base64Data的toString方法,跟进
这里触发了自身的get方法,跟进
这里关键代码是InputStream is = this.dataHandler.getDataSource().getInputStream();
1.这里也就是获取Base64Data的dataHandler的DataSource属性值,而这可以从xml中赋值,在POC中DataSource赋值为com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource,也就是this.dataHandler.getDataSource()值为com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource
2.随后程序执行com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource类的getInputStream方法,这将获取com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSourc的is属性值
在xml中已经定义了com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSourc的is属性值为java.io.SequenceInputStream
跟进readFrom方法
跟进read方法
跟进nextStream方法
e的值,可以通过向xml中SequenceInputStream元素中的e元素值来控制。在poc中将这个e元素值设置为javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator
跟进javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator的nextElement方法
在poc中同样为iterator赋过值,为javax.imageio.spi.FilterIterator,跟进next方法
跟进advance方法
这里的iter在poc中同样赋过值,为java.util.ArrayList$Itr
当iter.next()执行后,poc中构造的java.lang.ProcessBuilder被返回并赋值给elt
这里的filter同样被赋过值,为javax.imageio.ImageIO$ContainsFilter
跟进filter.filter(elt)
此时method为ProcessBuilder类的start方法,而通过上文可知:elt为构造好的java.lang.ProcessBuilder对象。在method与elt都可控的情况下,进行反射调用即可实现远程代码执行利用
CVE-2020-26259
漏洞分析
poc:
1 | <map> |
这个洞和上面的rce流程前面一致,直接看到分开的地方,26259触发点是is.close
因为在poc里is被赋值为com.sun.xml.internal.ws.util.ReadAllStream$FileStream,所以跟进close方法
这里的tempFile不为空则删除,tempFile在poc里面赋值为/Users/ghtwf01/test.txt,这个是自定义的所以就形成了任意文件删除漏洞。