前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从反射链的构造看Java反序列漏洞

从反射链的构造看Java反序列漏洞

作者头像
FB客服
发布2018-02-27 12:02:27
1.1K0
发布2018-02-27 12:02:27
举报
文章被收录于专栏:FreeBufFreeBuf

概况

今天我想从构造反射链的从无到有到被利用来谈谈java的反序列化漏洞,从反射的最开始到执行payload,一个从无到有的过程,首先我们介绍一下Transformer类。

Transformer**类介绍**

打开org.apache.commons.collections.Transformer类,可以看到源码中对该类的解释是从一个对象变为另一个对象,如下图所示:

从上图我们可以看到,里面有一个transform方法,通过描述我们理解为执行转变的方法,下面用一个简单的例子,解释一下这个类的作用,如下图所示:

当输入Runtime.class时,transform方法中输出了类的类型,如上图中红线处所示,当我需要转变对象时,相应的操作应该在transform方法当中。

我们查找有哪些类使用了Transformer接口,有如下几个类分别是ConstantTransformer,invokerTransformer,ChainedTransformer,TransformedMap。

下面我们利用以上的三个类一边构造出反序列漏洞的payload一边看他们的运作原理。

ConstantTransformer

通过查看源码,我们看到该类使用了Transformer的接口,重写了transformer的方法,如下图所示:

上面两幅图,可以看出transform返回的是iConstant的变量,iConstant的变量必定在ConstantTransformer(Object)方法中被赋值。

下面举个例子详细看使用,根据上图中的代码,如下图所示:

此时根据源码,我需要查看返回的iConstant对象类型,在源码中设置断点,开启debug运行,运行结果如下图:

上图中可以看到,内部构造出Runtime的对象类型。

InvokerTransformer

打开invokerTransformer查看源码的解释,可知是通过反射创建一个新的对象实例,如下图所示:

看到也使用了Transformer的接口,查看其transform方和和构造方法如下图所示:

上图中所示,构造函数会将iMethodName和iParamType的值传递进来,在transform方法中通过反射的方法,得到了这个方法的对象,最后返回的是Method对象。

使用举例,根据上述源码构造一个对象,并且调用transform对象,如下图所示:

在源码中设置断点,开启debug模式,进行分析,如下图所示:

参数传递进来,继续跟踪到transform函数当中,如下图所示:

继续跟踪查看method变量的值如下图所示:

这里解释一下下图中三行代码的意思:

cls变量获取到的是传递进来的input的对象值,此处input传递的是Runtime的对象,下面两行代码要反射Runtime的getRuntime方法,iMethodName表示要得到的方法名称,iParamTypes表示方法中所使用的参数类型的数组。

此处的iMethodName需要Mehtod对象,因此此处是getMethod,因此iParamTypes对应的是getMethod对象的参数类型集合,getMethod方法文档如下图所示:

通过查阅官方文档,我们知道了参数应该是String.class和Class[].class

继续往下执行invoke方法,因为是反射getRuntime()方法,参数为空,所以iArgs的值可以为空,回到主程序代码可以发现为null,如下图所示:

执行完毕之后,输出如下图所示:

成功的反射出了Runtime.getRuntime()的方法,然而如果要执行任意代码的化,还需要有exec代码段,全部应该是Runtime.getRuntime().exec(“calc.exe”)。

构造payload

此时我们已经获得了GetRuntime()的Method对象,如果要执行exec(“calc.exe”),我们还需要进行一次invoke反射的过程,因此我们根据上面构造出下面的代码段,如下图:

上图中,构造出tran2的方法,配置invoke的参数都为null,利用tran2.transform(run),反射invoke方法,过程与上文中一样,此处直接看输出了:

此处已经是Runtime类了,继续构造exec(“calc.exe”)代码段,如下图所示:

重复上面的步骤,运行代码如下图所示:

成功弹窗,以上是构造反射链的过程,那么如何去让反射链执行呢,我们来看一下ChainedTransformer这个类,我觉得从名称上已经很能说明问题了,反射链,我们细细看一下这个类。

ChainedTransformer

看一下这个类的源码解释,如下图所示:

没有很特别的地方,是Commons Collections中的类,继续往下看:

这里很有意思啊,和上文中的InvokerTransformer如出一辙,利用for循环,对传入的transformers[i]运行transform方法,这里无非就是把我们上文的步骤利用一个for循环整合在了一起,现在我构造一个以数组为主的反射链进行弹窗,代码段如下图所示:

构造出了chain方法之后,还需要调用transform方法,至于传入的对象会被很快覆盖掉,所以input的类型可以任意。

执行如下图所示:

执行成功。

如何才能不通过调用transform方法执行反射链呢?

下面就要去寻找类了,寻找到调用了ChainedTransformer类中的transform方法的类,这个类叫TransformedMap,从名称来看就非常的相似,找到他的setValue方法,如下图所示:

看到了吗,只要我们控制valueTransformer的值为ChainTransformer对象就可以执行反射链了,找到他的赋值地点,如下图所示:

从以上两幅图可以看出,valueTransformer变量是可控的,只要在decorate方法中赋值即可,我们给出下面的代码段:

利用decorate为valueTransformer赋值,然后在最后一行触发了setValue方法,其他的都是为了满足这两个条件形成,执行截图如下:

总结

从以上分析我们可以得出,java反序列化漏洞,只要反射链构造合适,我们可以执行任意的java代码。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概况
  • Transformer**类介绍**
  • ConstantTransformer
  • InvokerTransformer
  • 构造payload
  • ChainedTransformer
  • 如何才能不通过调用transform方法执行反射链呢?
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档