反序列化的原理
首先是要继承Serialize类只有继承了这个类菜能够进行序列化,如果某一个类没有继承serialize类并在一条利用链中所需要的地方,我们就可以通过反射来进行处理。例如在java中Runtime.getRuntime()是没有继承seralize类的
但是Runtime.class是继承了的
这样以来就可以通过反射来进行序列化和反序列化,反射核心代码如下
上面的代码都是可以成功弹出计算器的。利用链的构造尝试使用同名不同类的方法来进行调用。在这里就是复习一下反射的基本知识点,下面就开始进入正题
CC1链分析
分析之前还是要先记录下自己的想法以便于后续查看,在Java的序列化和反序列化中最终的目的就是达到任意命令执行,与其相关以及利用链的最终目的地就是找到可控的readObject(),从而成功利用,如下图所示
只要循序渐进的去找就能够得到一条利用链,可控的输入方法为transform,往前找不同类的相同方法,在org/apache/commons/collections/functors/InvokerTransform.java中看到了一个transform的调用,而且传入的参数也是可控的,可以通过反射调用来实现任意命令执行。分析下其中的代码
传入的三个参数
第一个参数传入的为方法名,后买那两个都是数组,成功的弹出计算器
然后再去逆推后面的链,发现 TranformedMap 中的 checkSetValue 方法调用了 transform
由于TransformedMap构造方法为protected,所以接着看代码是否存在public的调用方法
接下来就是去找如何调用checkSetValue(),调用如下
尝试写payload测试下,TransformedMap.decorate()传入三个参数,第一个为ma