java序列化漏洞_Java反序列化漏洞研究

漏洞原理

java序列化就是把对象转换成字节流,便于保存在内存、文件、数据库中;反序列化即逆过程,由字节流还原成对象。当反序列化的输入来源于程序外部,可以被用户控制,恶意用户便可以构造恶意的字节流,经反序列化之后得到精心构造的恶意对象。

也就是说一些java应用的数据在网络中传输,我们把里面的序列化数据抠出来,替换成我们的payload,应用程序接收之后把payload进行反序列化,构造的恶意功能(如命令执行)就被执行了。

4bf6bf609edde09d1985b39478a8d512.png

实际过程中直接忽略PCA的存在,hacker先于PCB完成一些前期的交互。

那么问题来了,如何构造能执行任意命令的payload?需要依赖于什么条件? 哪些应用会在网络中传输序列化的数据?这些数据有什么特征?序列化与反序列化原理

e08d693e3fc68fc1e092ab140bfa1892.png

上述代码说明了反序列化的过程,Java中通过writeObject()函数对对象进行序列化,将有结构的数据转换成为无结构的二进制串。 通过readObject()函数将二进制串反序列化还原成对象。

执行到12行时生成了一个String类型的对象。

执行到16行已经将序列化数据写入到object.db中了,前面的四个字节AC ED 00 05开头,后面会经常用到。

执行到24行,完成反序列化过程,将对象还原,此时对象id不同,其他均相同。构造执行任意命令的payload

下面的代码能快速的体验payload是如何构造的。

2d053aeeae1a2095c60be68d420d7132.png

程序1的RunInvo类,构造了一个MAP,再用它构造AnnotationInvocationHandler对象,将这个对象序列化到payload.bin中。

f50f71f384832652c2cce0f27e12efb4.png

程序2读取payload.bin中的数据,通过readObject()进行反序列化,代码得到执行,弹出计算器,如下图所示。

01837de68799cf0e4d65dbb950ccbdb5.png

代码执行关键点:AnnotationInvocationHandler,TransformedMap.decorate,InvokerTransformer

从序列化数据传入readObject()开始解释为什么要依赖于这几个关键点。

首先在序列化和反序列化的过程中,每个类都有自己的readObject与writeObject对应,很多类自己重写了自己的readObject与writeObject函数,String类有自己的readObject方式,AnnotationInvocationHandler也有自己的readObject方式。而AnnotationInvocationHandler的readObject实现调用了setValue()函数,这一特性将会被TransformedMap.decorate用到。

TransformedMap的decorate(Map map, Transformer keyTransformer, Transformer valueTransformer)函数,会将Map {key:value}按后面两个传入的函数参数来进行转换,当key或者value改变时(调用setValue),decorate就会被触发,而Transformer可以是一个调用链ChainedTransformer。这个调用链是通过InvokerTransformer精心构造的。

InvokerTransformer函数只需要传入方法名,参数类型,参数即可调用任意函数。通过这个函数构造调用链能够执行Runtime.exec()。而InvokerTransformer存在于Apache Commons Collections的库中,因此目标应用中需要有这个库,函数才能得到执行。

Payload的构造与触发流程如下图所示

f0b6efb0a8a4be701aee02abd1e279a5.png

几个关键函数原型可参考http://www.slideshare.net/codewhitesec/exploiting-deserialization-vulnerabilities-in-java-54707478

只有InvokerTransformer依赖于Apache Commons Collections库,其他函数都是通用的java库,所以payload执行的依赖条件只需目标java应用包含了Apache Commons Collections库即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值