发布网友 发布时间:2022-09-19 13:15
共1个回答
热心网友 时间:2023-10-28 02:12
当服务器收到序列化对象数据后,会调用对象类的readobject()方法进行反序列化,这里我们构造的恶意序列化对象使用的是AnnotationInvocationHandler类的实例化对象。所以当服务器收到这个对象时会去调用该类的readobject()方法进行反序列化,下面我们跟着上面的触发流程进行一步步触发分析。
结论:在漏洞触发的第一步中,在反序列化我们向服务器发送的恶意序列化AnnotationInvocationHandler对象时会触发对构造该类对象时传入的Map类型对象的第一个键值对的value进行修改。
当通过迭代器对象对TransformedMap类型的value值进行修改时会调用AbstractInputCheckedMapDecorator(TransformedMap类的父类并实现了 Map.Entry接口)中的内部类MapEntry的setValue()方法,debug运行可以看到this.parent变量值是TransformedMap对象的第一个键值对。
结论:在漏洞触发的第二步中,触发了TransformedMap的checkSetValue()方法
可以看到ChainedTransformer对象的transform()方法的功能是将传入的对象交给对象中的this.iTransformers变量引用的对象的transform()方法进行处理。this.iTransformers变量引用的对象从53行可知是对象实例化时传入的,从poc的25行可知我们实例化时传入一个Transformer[]的数组。
结论:在漏洞触发的第三步中,TransformedMap.checkSetValue()触发ChainedTransformer.transform()方法。ChainedTransformer.transform()方法将传入的对象经过ChainedTransformer对象中的各个Transformer类型的实例对象调用实例化对象的transform()方法处理。
由poc 20-25行可知ChainedTransformer对象中的Transformer类型的实例对象分别是ConstantTransformer、InvokerTransformer,首先触发ConstantTransformer对象的transform()方法,可以看出ConstantTransformer对象的transform()方法的功能是将传入的对象转换成实例化ConstantTransformer对象时传入的对象,由poc的21行可知实例化ConstantTransformer对象时传入的对象为java.lang.Runtime.class,因此经过ConstantTransformer.transform()后传入的参数变成了类对象java.lang.Runtime.class,再经过InvokerTransformer.transform()处理。
从59-61行可以看出InvokerTransformer.transform()功能是通过反射得到传入对象中方法名为this.iMethodName参数类型为this.iParamTypes的方法,并执行该方法传入的方法参数为this.iArgs。而this.iMethodName、this.iParamTypes、this.iArgs三个参数都是我们在实例化InvokerTransformer对象时自定义的,这导致可以进行任意命令执行。
第一次执行InvokerTransformer.transform()方法后
第二次执行InvokerTransformer.transform()方法后
第三次执行InvokerTransformer.transform()方法
结论:在漏洞触发的第四步中,传入的对象经过1次ConstantTransformer.transform()与3次InvokerTransformer.transform()转换触发exec()任意命令执行。
ps:jdk版本需要1.7