美文网首页
JAVA反序列化中的反射链

JAVA反序列化中的反射链

作者: sum3mer | 来源:发表于2017-12-04 10:32 被阅读0次

    从反射链的构造看JAVA反序列化

    http://www.freebuf.com/news/150872.html

    构造反射链:Transformer类,源码解释为从一个类转化为另一个类。其中的transform()为执行转换方法。

    ConstantTransformer,invokerTransformer,ChainedTransformer和TransformedMap继承了Transformer类。利用它们来构造反序列化payload,原理为:

    ConstantTransformer类通过transform转换得到内部类的对象类型,如参数是Runtime.class时,经ConstantTransformer类执行后返回java.lang.Runtime

    invokerTransformer类,通过反射创建新的对象实例。其中transform方法定义为:

    这个transform(Object input) 中使用Java反射机制调用了input对象的一个方法,而该方法名是实例化InvokerTransformer类时传入的iMethodName成员变量:

    也就是说这段反射代码中的调用的方法名和Class对象均可控。于是,我们可以构造一个恶意的Transformer链,借用InvokerTransformer.transform()执行任意命令。

    method.invoke(input,iargs)意思是,执行input对象的method方法,参数是iargs。

    举例:构造一个对象,并且调用transform对象,如下图所示:

    查看method变量的值如下图所示:

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

    执行invoke方法,因为是反射getRuntime()方法,参数为空,所以iArgs的值可以为空。成功的反射出了Runtime.getRuntime()的方法,然而如果要执行任意代码的化,还需要有exec代码段,全部应该是Runtime.getRuntime().exec(“calc.exe”)。

    构造payload

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

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

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

    由此构造成功payload。

    以上是构造反射链,执行反射链用到ChainedTransformer。

    利用for循环,对传入的transformers[i]运行transform方法,就是把上文的步骤利用一个for循环整合在了一起。

    现在我构造一个以数组为主的反射链进行弹窗,代码段如下图所示:

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

    TransformedMap类

    这个类调用了ChainedTransformer类中的transform方法。transform函数调用在TransformedMap类的setvalue方法中。

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

    当TransformedMap内的key 或者value发生变化时,就会触发相应的Transformer的transform()方法。另外,还可以使用Transformer数组构造成ChainedTransformer。当触发时,ChainedTransformer可以按顺序调用一系列的变换。

    payload测试代码:

    InvokerTransformer.transform()执行任意命令,测试代码如下:

    这样,这段恶意代码本质上就是利用反射调用Runtime() 执行了一段系统命令,作用等同于:

    也就是说,一个精心构造的TransformedMap,在其任意键值被修改时,可以触发变换,从而执行任意命令。

    相关文章

      网友评论

          本文标题:JAVA反序列化中的反射链

          本文链接:https://www.haomeiwen.com/subject/ufavbxtx.html