1. Fasterxml 远程代码执行1
1.1 威胁等级
严重
1.2 影响范围
Fasterxml Jackson-databind < 2.9.0
1.3 利用难度
困难
1.4 漏洞描述
FasterXML远程代码执行漏洞是由于JNDI注入导致远程代码执行, Jackson-databind < 2.9.0版本中缺少com.sun.rowset.JdbcRowSetImpl黑名单类,攻击者可以利用上述缺陷,绕过限制,实现JNDI注入,最终在受害主机上执行任意代码。
1.5 漏洞分析
首先定位到com.sun.rowset中的JdbcRowSetImpl类,搜索用于jndi连接的lookup方法,可以定位到326行如下:
可以看出这里面lookup方法将dataSourceName的值当做JNDI连接的地址,并且只要调用connect方法时conn为空且dataSourceName不为空即可触发,于是继续寻找connect方法的调用位置。
最终定位到我们想要的set方法中,到此,payload的构造的方法就呼之欲出了。
通过上述漏洞触发点的分析,容易看出只需要最终反序列化时能够成功调用setAutoCommit方法即可。并且根据fasterxml反序列化的特性,反序列化时会调用给定属性的set方法,于是这里面我们只需要对包含JNDI地址的传入数据进行反序列化即可。给出整个的调用栈如下:
首先进入反序列化入口如下:
这里面的readValue是使用set方法将rmi的值设置进去,后面的writeValueAsString则再次进行序列化,使用get方法。此漏洞中,直接在反序列化过程中使用set方法即可触发漏洞。
进入ObjectClass类的readValue方法
这里面将传入的payload和Object分别封装在两个类中,并进行下一步的处理。接着进入到ObjectMapper类中的_readMapAndClose方法中:
第1528行的_initForReading方法获取了正常情况下(即以’[‘开始)的标识位START_ARRAY,接着进入1534行的else,首先是获取到序列化配置信息cfg, 接着将其和将要解析的内容p一起放置在ctxt中,而findValueDeserializer则可以获取带有valueType的序列化器。接着会进入1540行开始进行反序列化。
然后不断下移,一直进入到UntypedObjectDeserializer类的deserializeWithType方法,继续进入序列化
一直到AsArrayTypeDeserializer类中的_deserializer方法
其中第67行获取到了该类字符串,单步进入68行的TypeDeserializerBase类中的_findDeserializer方法
其中86行因为this._deserializer是空的,所以deser也是null,88行实现了payload中类的反射,104行将反射出的类放入到了序列化器中。
下面进入到BeanDeserializer类中的vanillaDeserialize方法中
第189行确认了payload中的属性,如果出现不存在的属性就会在这里出现问题。接着进入198的序列化。
最后进入到MethodProperty类中的deserializeAndSet方法中:
78行的invoke将会一步步嵌套调用到set方法来设置属性,并触发上述提到的lookup方法实现攻击。
首先通过github的补丁比较,可以发现在BeanDeserializerFactory类中将该恶意类加入到了黑名单中
下面来分析一下该黑名单是怎么实现防护的。继续深入代码查看,回到上面ObjectMapper类中的_readMapAndClose方法中,第1536行中的方法内部就对黑名单进行了过滤,接下来继续深入该方法。
然后不断深入,在反射出恶意类时继续进入DeserializerCache类的_createAndCacheValueDeserializer方法的第113行的方法
一直进入到BeanDeserializerFactory类中的createBeanDeserializer方法如下:
可以轻松发现其中的checkIllegalTypes方法,进入查看
这里面就用到了前面的黑名单,一旦包含恶意类,就将报错退出。
另外,这里需要提到的一点是,fasterxml的黑名单变更过位置: