TemplatesImpl在反序列化链中的作用

起因

TemplatesImpl这个东西经常在java反序列化加载恶意类的时候见到,还是要详细看一下执行流程

通过ClassLoader加载字节码

我们都知道Java中ClassLoader是用来加载字节码文件最基础的方法,可以将Java的字节码转为Java虚拟机中的类

但是在正常情况下,由于defineClass是一个protected方法,我们调用它去加载也只能通过反射调用,所以实际反序列化利用的时候直接利用并不现实(毕竟反序列化并不能直接进行反射操作)

那么这时有人发现TemplatesImpl重写了defineClass方法,并且这个类并没有定义作用域,在Java中相当于定义作用域为default,那么这里的defineClass方法就从父类的protected方法变成了default方法

这时候我们就可以从外部调用defineClass方法了(它甚至自动帮你写length,我哭死)

不过此时的defineClass依然定义在TransletClassLoader中,只能被类内的方法调用,所以我们需要找到使用了TransletClassLoader的类

private synchronized Class[] getTransletClasses()
要求_class为null
private Translet getTransletInstance()
要求_class为null且_name不为null
public synchronized int getTransletIndex()
要求_class为null

俩私有一个公有,是我我肯定选公有那个,但是公有的直接调用会因为不明原因并没有进行加载(感觉是synchronized的原因),所以我们只能继续向上找

找到newTransformer,在执行transformer = new TransformerImpl(getTransletInstance(),_outputProperties,_indentNumber, _tfactory);时会执行getTransletInstance进而执行

最后能找到的两条链子是

getOutputProperties()->)newTransformer()->getTransletInstance()->defineTransletClasses()

对属性的要求是

_bytecodes被赋值为我们定义的恶意类的字节码,该类需要继承com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet,这个部分不继承抛出一次error你就知道了
_class必须为null
_name必须不为null
_tfactory必须是TransformerFactoryImpl实例

最后关于为什么上面的public不能直接用的原因,是因为其中defineClass是不会自动执行构造方法的,甚至静态代码块也是不会执行的,所以我们实际上不仅需要执行defineClass,还需要进行newInstance操作对类进行实例化(无参),可以看到三个方法中只有getTransletInstance进行了newInstance操作,这里也再次重申了需要进行继承AbstractTranslet