欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

CVE-2019-12384:Jackson反序列化漏洞分析

来源:本站整理 作者:佚名 时间:2019-07-25 TAG: 我要投稿

在某次渗透测试过程中,我们分析的某个应用使用Jackson库来反序列化JSON数据。经过分析后,我们找到了一个反序列化漏洞,可以用来控制待反序列化的类。在本文中,我们将分享攻击者如何利用这个反序列化漏洞发起SSRF(服务端请求伪造)以及RCE(远程代码执行)之类的攻击。
漏洞对应的编号为CVE-2019-12384,RedHat的多个分支受该漏洞影响,如下所示:

 
0x01 利用条件
根据Jackson开发者在某篇文章中提到的信息,触发这个Jackson漏洞需要满足如下要求:
1、目标应用接收来不可信客户端发送的JSON数据(可以手动编写代码或者使用不透明或者不可控的代码),这意味着我们无法约束正在发送的JSON数据;
2、目标应用使用多态类型处理方式来处理java.lang.Object类型(或者少数几个可使用的接口,如java.util.Serializable、java.util.Comparable)的属性;
3、目标应用至少包含能够在Java classpath中利用的一个“gadget”类。漏洞利用过程中需要用到能够配合Jackson的一个类。实际上,大多数gadget只能配合特定库使用,比如之前多次讨论过的JDK序列化场景;
4、目标应用使用的Jackson并没有阻止这个特定的“gadget”类。随着时间的推移,已发布的gadget数量越来越多,因此我们需要在gadget发现、报告和修补过程中占得先机。Jackson维护着一个黑名单列表,反序列化是平台的一个“功能”,官方会不断更新已报告的gadget黑名单。
在此次研究过程中,我们假设利用场景已满足条件1及条件2。实际上,我们重点寻找的是能够满足条件3及条件4的gadget。需要注意的是,Jackson是Java应用程序中最常使用的反序列化框架之一,而多态(polymorphism)是其中最重要的一个概念。如果攻击者使用静态分析工具或者其他动态分析技术(比如在请求/响应中grep查找@class)来寻找满足这些条件的利用点,那么这些目标定位起来并不是特别难。
 
0x02 环境准备
在研究过程中,我们开发了一款工具来帮助分析这类漏洞。当Jackson反序列化ch.qos.logback.core.db.DriverManagerConnectionSource时,我们可以滥用这个类来实例化JDBC链接。JDBC的全称是“(J)ava (D)ata(b)ase (C)onnectivity”,这是一个Java API,用来连接数据库并执行查询语句,也是JavaSE(Java Standard Edition)的一部分。此外,JDBC使用了字符串到类的自动化映射,因此在整条攻击链中,这是用来加载并执行更多“gadget”的绝佳目标。
为了演示攻击过程,我们准备了一个封装器(wrapper),用来加载攻击者指定的各种多态类。在环境方面,我们使用的是基于Java虚拟机(JVM)的jRuby,用来加载并实例化Java类。
我们使用该环境来加载指定目录中的Java类,准备满足条件1及条件2的Jackson环境。为了完成该任务,我们开发了如下jRuby脚本:
require 'java'
Dir["./classpath/*.jar"].each do |f|
    require f
end
java_import 'com.fasterxml.jackson.databind.ObjectMapper'
java_import 'com.fasterxml.jackson.databind.SerializationFeature'
content = ARGV[0]
puts "Mapping"
mapper = ObjectMapper.new
mapper.enableDefaultTyping()
mapper.configure(SerializationFeature::FAIL_ON_EMPTY_BEANS, false);
puts "Serializing"
obj = mapper.readValue(content, java.lang.Object.java_class) # invokes all the setters
puts "objectified"
puts "stringified: " + mapper.writeValueAsString(obj)
脚本主要执行如下操作:
1、第2行,加载classpath子目录中JAR中包含的所有类;
2、第5-13行,配置Jackson以满足漏洞利用条件;
3、第14-17行,反序列化及序列化以JSON形式传递给jRuby的一个Jackson多态对象。
 
0x03 Gadget
在此次研究中,我们决定使用Java社区中广泛使用的gadget。我们的目标库为Maven中排名前100位的所有库,以便演示攻击影响。
如果大家想复现攻击过程,可以下载如下程序库,将这些库存放在classpath目录中:
jackson-databind-2.9.8
jackson-annotations-2.9.8
jackson-core-2.9.8
logback-core-1.3.0-alpha4
h2-1.4.199
需要注意的是,SSRF攻击中并不需要使用h2库,因为根据我们的经验,大多数情况下Java应用至少会加载一个JDBC驱动。JDBC驱动也是一种类,当传入JDBC url时会被自动实例化,完整URL会以参数形式传入处理。
我们可以使用如下命令来调用之前开发好的脚本:
$ jruby test.rb "["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:"}]"
在脚本第15行,Jackson会使用子对象中的键值递归调用所有set方法。更具体一些,Jackson反射库会调用setUrl(String url),传入所需参数。此后(第17行),整个对象会被再次序列化为一个JSON对象。如果没有定义任何get方法,或者通过显示get方法,此时所有的字段都会被直接序列化。对我们来说比较有趣的是getConnection()。作为攻击者,实际上我们感兴趣的是所有的“non pure”(“非纯”)方法,通过控制参数,这些方法会存在一些有趣的“副作用”。
当调用getConnection时,代码会实例化一个内存数据库。由于目标应用生存周期较短,从攻击者视角来看,我们看不到任何影响。为了完成更有意义的任务,我们创建了到远程数据库的一个连接。如果目标应用以远程服务方式进行部署,那么攻击者可以达到SSRF(Server Side Request Forgery)效果,典型攻击场景如下图所示:

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载