Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【技术分享】jackson反序列化详细分析

$
0
0
【技术分享】jackson反序列化详细分析

2017-07-18 15:00:11

阅读:1223次
点赞(0)
收藏
来源: 安全客





【技术分享】jackson反序列化详细分析

作者:PandaIsCoding





【技术分享】jackson反序列化详细分析

作者:PandaIsCoding

预估稿费:300RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


前言

这是今年四月份被公开的jackson反序列化漏洞,不过目前看来利用比较鸡肋,本篇只以技术学习的角度来分析这个漏洞,如有问题,还望大牛批评指出。


漏洞情况

Jackson是一套开源的java序列化与反序列化工具框架,可将java对象序列化为xml和json格式的字符串及提供对应的反序列化过程。该漏洞的触发条件是ObjectMapper反序列化前调用了enableDefaultTyping方法。该方法允许json字符串中指定反序列化java对象的类名,而在使用Object、Map、List等对象时,可诱发反序列化漏洞,导致可执行任意命令。


影响版本

Jackson 2.7(<2.7.10)

Jackson 2.8(<2.8.9)


环境

Jackson-2.8.8.jar

Jdk1.7.0_45(这里分析使用jdk1.7, 不能使用jdk1.8之上的版本,后面会解释说明)。

我们先看下漏洞的poc。

User.java:


【技术分享】jackson反序列化详细分析

Exp.java:


【技术分享】jackson反序列化详细分析

Main.java:


【技术分享】jackson反序列化详细分析

首先jackson会解析要转化json数据中的类,提取出类的变量和相应方法。我们在

BeamnPropertyMap.class->init(Collection<SettableBeanProperty> props)最后

_hashArea = hash处下上断点可以看出User.class的信息。


【技术分享】jackson反序列化详细分析

然后BeanDeserializer.class->vanillaDeserialize()函数,该函数会遍历json数据的key-value,

并将类中key变量设置为value值。


【技术分享】jackson反序列化详细分析

根据构造的json数据,jackson会首先设置User类object的值。

由于object的值是com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl。

Jackson会首先设置TemplatesImpl相关变量。

程序再次进入BeamnPropertyMap.class->init(Collection<SettableBeanProperty> props),在_hashArea中我们可以看到TemplatesImpl类的相关信息。


【技术分享】jackson反序列化详细分析

其中有三个是我们通过json传入得参数,其对应的函数分别为

transletBytecodes:privatesynchronizedvoidcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.setTransletBytecodes(byte[][]), outputProperties:publicsynchronizedjava.util.Propertiescom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties(), transletName:protectedsynchronizedvoidcom.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.setTransletName(java.lang.String),

然后程序进入vanillaDeserialize函数,按照我们构造json数据 的key的顺序开始设置value值。


【技术分享】jackson反序列化详细分析

然后进入deserializeAndSet()函数,先调用setTransletBytecodes()函数设置


【技术分享】jackson反序列化详细分析

transletBytecodes的值。此时value值就是我们的exp数据。

然后调用setTransletName()函数设置transletName的值,此时的value就是我们传入得”p”.


【技术分享】jackson反序列化详细分析

最后一次循环处理key为outputProperties的情况。程序执行了getOutputProperties()方法。弹出计算器。


【技术分享】jackson反序列化详细分析

为什么执行getOutputProperties()函数后就算执行我们的exp呢(这里弹出计算器),这里其实就是反序列化payload的构造问题了。这里是通过TemplatesImpl类来实现的反序列化利用的。其实就是TemplatesImpl中有个_bytecodes变量,用来存放类的字节的,当我们调用getOutputProperties()函数,就会加载bytecodes中的类,执行了我们的代码。相关内容具体可参考:http://drops.xmd5.com/static/drops/papers-14317.html这篇文章。

新版本的2.8.9就对反序列化所用的一些类进行了过滤:


【技术分享】jackson反序列化详细分析

添加了一个函数判断,来检测是否加载的类为反序列化漏洞常用类,如果是则报错。


【技术分享】jackson反序列化详细分析

现在回到一开始说的jdk的问题,最初测试时我是在jdk1.8.0_45环境下测试的,发现无法弹出计算器。然后又用了jdk1.7才弹出计算器的。

想想应该是jdk1.7到jdk1.8,com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl类有了变化,才导致反序列化利用失败的。

为了找到原因,我看了下jdk1.7 和jdk1.8中com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl类 调用getOutputProperties()执行流程有什么变化。

发现在getOutputProperties()调用后,执行defineTransletClasses()时两个版本有所区别。

Jdk1.7:


【技术分享】jackson反序列化详细分析

Jdk1.8:


【技术分享】jackson反序列化详细分析

可以看到jdk1.8多了个_tfactory.getExternalExtensionsMap()的处理。我们在jdk1.8的环境下跟踪下程序,发现到这里_tfactory的值为null,所以执行_tfactory.getExternalExtensionsMap()函数时会出错,导致程序异常,不能加载_bytecodes的中的类。


【技术分享】jackson反序列化详细分析

因为我们在构造json数据时,对com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl只设置了三个变量。没有设置_tfactory的值,所以这里_tfactory为null。

后来想想只要在构造json数据时,设置_tfactory的值,也许就能在jdk1.8下执行,测试时并没有成功,还是too young, too simple, sometimes naive。


【技术分享】jackson反序列化详细分析

由上图可知,在jackson初始化com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl并没有获取设置_tfactory的相关函数,所以也无法设置_tfactory的值。目前还未想出来如何绕过。


参考

http://bbs.pediy.com/thread-218416.htm

http://drops.xmd5.com/static/drops/papers-14317.html



【技术分享】jackson反序列化详细分析
【技术分享】jackson反序列化详细分析
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/4118.html

Viewing all articles
Browse latest Browse all 12749

Latest Images

Trending Articles





Latest Images