Java反序列化漏洞自动挖掘方法

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: Java反序列化漏洞自动挖掘方法

文章来源:蚂蚁非攻安全实验室 、先知白帽大会


一、序列化与反序列化


1、定义:序列化是用于将对象转换成二进制串存储,对应着 writeObject,反序列正好相反,将二进制串转换成对象,对应着 Freadobject


0a2653c851af460fa595bd959398a8f1.png


2、各编程语言都存在:


Java: java.io.Serializable接口、fastjson、jackson、gson


PHP: serialize()、 unserialize()


Python:pickle


3、使用场景


http参数,cookie,sesion,存储方式可能是base64(rO0),压缩后的base64(H4s),MII等


Servlets http,Sockets,Session管理器,包含的协议就包括:JMX,RMI,JMS,JND1等(\xac\Xed)


xm lXstream,XmldEcoder等(http Body:Content-type: application/xml)


json(jackson,fastjson)http请求中包含



二、Java反序列化过程


1. 对象实例化


sun.misc.Unsafe#allocateInstance


通过反射调用构造函数


0eacb84100b54626af849e6b562bf92a.png


2. 成员变量还原


Setter和getter方法


通过反射直接设置


成员变量的处理(例如:PriorityQueue)


2d65d23f6d4748949b924e4057485923.png


三、Java反序列化漏洞(PriorityQueue)


0a2653c851af460fa595bd959398a8f1.png


四、Java反序列化漏洞挖掘


1、寻找一个类,通过构造一个对象,使其在被反序列化时能执行到危险(sink)方法。


0eacb84100b54626af849e6b562bf92a.png


2、寻找一个类,存在可能的执行路径,从反序 列化入口(source)方法执行到危险(sink)方法自动化搜索)


3、构造这个对象,使危险(sink)方法参数可控。(手工打造)



五、 自动化挖掘实现


1、在静态分析中,这是一个典型的可达性分析问题。


2d65d23f6d4748949b924e4057485923.png


2、 可达性分析 - may分析:无需绘制控制流图,只需搜素调用树。


2e9b90b2ca334476abebe75bafe6eeaa.png


六、、 调用树搜索实现


1、深度优先搜索(DFS) vs 广度优先搜索(BFS)


调用路径越长,payload越难构造 ;搜索深度有限 ;等价于搜索一个n叉树(n>100)的前几层;调用链的存储


0a2653c851af460fa595bd959398a8f1.png


2、深度优先搜索(DFS)


搜索停止条件:到达指定深度;搜索到sink方法


搜索结果保存: 使用stack保存路径


0eacb84100b54626af849e6b562bf92a.png


七、搜索中的多态问题


1、由于面向对象中多态性的存在,只有在运行时 才能确定调用哪个子类的eat方法。


2d65d23f6d4748949b924e4057485923.png


2、多态的处理


构建类、接口和方法继承树(双向树)


寻找调用的方法的实现所在类的所有子类集合


在上述集合中寻找调用者类的子类的集合


这些子类中重写的方法即为所有可能调用的方法


八、路径成环


搜索到CircleChain的hashCode方法时,这个方法调用了Object#hashCode方法,寻找Object的子类会再找到CircleChain


类,形成环。


2e9b90b2ca334476abebe75bafe6eeaa.png


九、路径爆炸


以下方法的实现会造成路径爆炸


1、Java.util.List#get方法


2、Java.lang.Object#toString方法


3、java.util.Iterator#hasNext方法


0a2653c851af460fa595bd959398a8f1.png0eacb84100b54626af849e6b562bf92a.png


十、路径爆炸成环问题解决


1. 搜索深度限制(兜底)


2. 已搜索方法缓存


1. 先缓存、后搜索


2. 缓存方法signature


4. 调用链缓存


2d65d23f6d4748949b924e4057485923.png


只需要构造C方法执行时的上下文,使其与链2一致即可


十一、Jackson反序列化漏洞挖掘


1、简介


Jackson是一个开源的Java序列化与反序列化工具,可以将java对象序列化为xml或json格式的字符串,或者反序列化回对应的对象,由于其使用简单,速度较快,且不依靠除


JDK外的其他库,被众多用户所使用。


Jackson也是Spring MVC默认的json解析库,打开多态之后,jackson会根据json中传入的类名进行反序列化


相比其他后来开发的json解析库来说,jackson有灵活的API,可以很容易根据需要进行扩展和定制。


2、Jackson历史漏洞


CVE-2017-7525:RCE


CVE-2017-17485:RCE


CVE-2018-14718:RCE


CVE-2019-12086:任意文件读取


CVE-2019-12384:RCE(要求反序列化后再序列化payload)


CVE-2019-14379:RCE (要求反序列化后再序列化)



3、Jackson反序列化过程


对象初始化:


调用类的无参初始化方法


调用包含一个基础类型参数的构造函数,并且这个参数可控


对象中成员变量赋值:


将json看成key-value对,key与field不一定一一对应。


首先看key是否存在setter方法,如果存在setter方法,则会通过反射调用setter方法


否则看在这个类中是否存在与key同名的field,如果存在,则通过反射直接赋值。


否则看是否存在对应的getter方法,且getter的返回值是Collection或者Map的子类,如果满足这个条件,则会调用这个getter方法


如果以上条件都不满足,则抛出异常


0a2653c851af460fa595bd959398a8f1.png


4、反序列化的source method


Jackson反序列化显式调用的方法:仅包含一个基本类型参数的构造函数;Setter方法;返回值是Collection或者Map的子类的getter方法;


反序列化过程中隐式调用的方法:hashCode;compare


5、Jackson反序列化的sink method


命令执行:


• java.lang.reflect.Method#invoke


• javax.naming.Context#lookup


• javax.naming.Context#bind


• java.lang.Runtime#exec


• java.lang.ProcessBuilder#ProcessBuilder


文件读取:


• java.sql.Driver#connect MySQL客户端任意文件读取


• org.xml.sax.XMLReader#parse


• javax.xml.parsers.SAXParser#parse


• javax.xml.parsers.DocumentBuilder#parse


6、Jackson反序列化漏洞搜索结果


CVE-2019-12086:


com.mysql.cj.jdbc.NonRegisteringDriver#connect(String, Properties)-->


com.mysql.cj.jdbc.admin.MiniAdmin#MiniAdmin(String, Properties)-->


com.mysql.cj.jdbc.admin.MiniAdmin#MiniAdmin(String)


CVE-2017-7525:


com.sun.jndi.toolkit.url.GenericURLContext#lookup(String)-->


javax.naming.InitialContext#lookup(String)-->


com.sun.rowset.JdbcRowSetImpl#connect()-->


com.sun.rowset.JdbcRowSetImpl#setAutoCommit(boolean)


javax.xml.parsers.SAXParser#parse(InputSource, DefaultHandler)-->


org.mortbay.xml.XmlParser#parse(InputSource)-->


org.mortbay.xml.XmlConfiguration#XmlConfiguration(String)


CVE-2019-12814


com.sun.xml.internal.fastinfoset.sax.SAXDocumentParser#parse(InputSource)-->


org.apache.xalan.processor.TransformerFactoryImpl#newTemplates(Source)-->


org.jdom.transform.XSLTransformer#XSLTransformer(Source)-->


org.jdom.transform.XSLTransformer#XSLTransformer(String)


禁止非法,后果自负


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
2月前
|
Java
Java语言实现字母大小写转换的方法
Java提供了多种灵活的方法来处理字符串中的字母大小写转换。根据具体需求,可以选择适合的方法来实现。在大多数情况下,使用 String类或 Character类的方法已经足够。但是,在需要更复杂的逻辑或处理非常规字符集时,可以通过字符流或手动遍历字符串来实现更精细的控制。
280 18
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
199 1
|
2月前
|
Java 编译器 Go
【Java】(5)方法的概念、方法的调用、方法重载、构造方法的创建
Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用方法的优点使程序变得更简短而清晰。有利于程序维护。可以提高程序开发的效率。提高了代码的重用性。方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。这种就属于驼峰写法下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。
222 4
|
2月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
225 1
|
2月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
320 5
|
3月前
|
算法 安全 Java
除了类,Java中的接口和方法也可以使用泛型吗?
除了类,Java中的接口和方法也可以使用泛型吗?
169 11
|
3月前
|
Java 开发者
Java 函数式编程全解析:静态方法引用、实例方法引用、特定类型方法引用与构造器引用实战教程
本文介绍Java 8函数式编程中的四种方法引用:静态、实例、特定类型及构造器引用,通过简洁示例演示其用法,帮助开发者提升代码可读性与简洁性。
|
4月前
|
算法 Java
Java语言实现链表反转的方法
这种反转方法不需要使用额外的存储空间,因此空间复杂度为,它只需要遍历一次链表,所以时间复杂度为,其中为链表的长度。这使得这种反转链表的方法既高效又实用。
443 0
|
安全 前端开发 Java
网站代码漏洞审计之JAVA架构
以前诸位看到过大牛的php代码审计,但是后来由于技术需要学了Java的代码审计,刚来时实战演练检测自个的技术成果,实际上代码审计我觉得不单单是取决于源代码方面的检测,包含你去构建布署下去和去黑盒测试方法作用点相匹配的源代码中去探索这一环节是最重要的,在代码审计中通常全部都是静下心去一步步的探索就可以峰回路转了!
247 0
网站代码漏洞审计之JAVA架构
|
3月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案