内容简介:0×00.背景介绍Java 十分受开发者喜爱的一点是其拥有完善的第三方类库,和满足各种需求的框架;但正因为很多第三方类库引用广泛,如果其中某些组件出现安全问题,那么受影响范围将极为广泛。本文我们将主要分析JDK7u21调用链。
0×00.背景介绍
关于 java 反序列化漏洞,最为出名的大概应该是:15年的Apache Commons Collections 反序列化远程命令执行漏洞和 2016年Spring RMI反序列化漏洞 ,其中 15年的Apache Commons Collections 反序列化远程命令执行漏洞 影响范围包括:WebSphere、JBoss、Jenkins、WebLogic 和 OpenNMSd等。 近几年比较出名的: Jackson,FastJson 。
Java 十分受开发者喜爱的一点是其拥有完善的第三方类库,和满足各种需求的框架;但正因为很多第三方类库引用广泛,如果其中某些组件出现安全问题,那么受影响范围将极为广泛。本文我们将主要分析JDK7u21调用链。
0×01.准备阶段
之前的调用链基本都是围绕的Java第三方包中的一些内容,但是随着JDK7U21的出现,彻彻底底的说明了反序列化根本不需要使用第三方库的支持。 而且JDK7u21的利用过程十分精彩,使用HashSet,TemplatesImpl和AnnoationInvocationHandler,其中后两个调用链频繁的出现在Collections调用链中,也都是十分经典的调用链。
关于HashSet这个容器,实际上就是底层使用了Hash表来实现的,它不允许元素重复,但它不保证顺序,这是和List的最大区别。
这一篇文章中,小豹准备分析调试一下JDK7u21这个调用链。
这里面的代码是直接使用ysoserial项目生成,直接输出到jdk7u21.cer文件中,然后进行反序列化。
java -jar ysoserial.jar Jdk7u21 "open /Applications/Calculator.app" > jdk7u21.cer
注意这里的JDK版本。
❱ ./java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b12)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
0×02.过程分析
当进行readObject操作的时候,发现它是一个HashSet,会直接调用HashSet的ReadObject。
在内部实现中使用了HashMap,这里在For循环中,会循环的进行反序列化,在ysoserial的payload中,实际上存储了2个对象,一个是恶意调用链TemplatesImpl,另一个是Proxy。所以这里的for循环会循环2次,每一次都put进HashMap中。 第一次反序列化是一个TemplatesImpl 然后put。
图中反序列化的e正是我们的TemplatesImpl,恶意代码存储在_bytecodes中。 然后进入put我们会发现,首先计算key的哈希,这个key就是我们上图中的e(TemplatesImpl),注意这个函数中还有个局部变量e,很容易混淆。 然后根据hash来计算在table中的索引。
由于现在第一次table中还没有数据,则e为空,不会进入到for循环,而是直接调用addEntry去添加元素。
本次计算的hash索引都在上图中,后面会用到。然后put函数结束,回到第二层循环,这次反序列化的实际上是一个Proxy,这个Proxy用来代理TempLatesImpl,使用动态代理的时候会直接调用到Handler中的invoke函数。 回到第二层循环中
这里反序列化的结果实际上就是Proxy,payload中被强制转换成上图红线标注的类。然后进入put,来计算proxy的hash。这个proxy的handler是AnnoationInvocationHandler
进入hash函数,发现是调用hashcode。
这里面的k就是上面传进来的Proxy,这里会触发动态代理机制,进入到handler中的invoke方法。
原来是调用handler中的hashCodeImpl方法。
在hashCodeImpl方法中,首先获得handler中memberValues的迭代器。这个memberValues就是我们构造的hashmap,key为“f5a5a608”他的hashcode是0,value是templatesImpl恶意调用链,也就是我们第一次put进去的对象。
由于这个hashmap只有一个元素,所以迭代器这里只会循环一次,就出去了。所以0和X亦或,还是X。最终返回的是templatesImpl恶意调用链的hashcode。注意这里就是精华之处了。hashCodeImpl函数结束完毕,会逐层返回到put中的hash函数
你会惊奇的发现hash值和我们前面第一次put时候的hash一模一样。这就造成了hashset第一个元素的hash和第二个proxy的hash一样,于是他们获得的索引值i也就一样。
这里的i同样也是5。那现在和第一次执行put的时候完全情况就不一样了,第一次我们是由于table返回的e是空的,没有进入到循环中,直接进行add添加元素。这次i为5,正好e是TemplatesImpl对象。e不为空会进去到循环。
进入到循环之后,会调用key.equals函数。key的本质是proxy啊。会继续触发动态代理。
会去执行invoke,去调用equalsImpl方法。
equalsImpl方法会触发我们的恶意代码
首先获取所有的methods。然后循环的invoke。第一次invoke的函数是var5。我们可以看到第一个就是newTransformer函数。剩下就是TemplatesImpl子调用链的过程了,详细可以参考其他文章(关于TemplatesImpl调用链本文暂不调试)。newTransformer函数就会导致bytecodes的加载。
这个调用链的思路和collections差别挺大的。
以上所述就是小编给大家介绍的《JDK7u21调用链分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 汇编层面分析函数调用
- 无限调用之链模式分析
- 漏洞分析连载第十四期 | 拘于小节的调用权限,函数调用权限漏洞
- [Masonry] 实现原理及链式调用分析
- 一种用来检测分析异常代码调用栈的可视分析方法。
- JVM指令分析实例三(方法调用、类实例)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。