fastjson反序列化的两种利用方法的原理剖析
JdbcRowSetImpl
利用JdbcRowSetImpl的payload如下:
1 | { |
在触发反序列化时会调用JdbcRowSetImpl类的 setAutoCommit函数
1 | public void setAutoCommit(boolean var1) throws SQLException { |
继续跟进connect函数
1 | protected Connection connect() throws SQLException { |
可以看到当conn为null时会发起JNDI查询从而加载我们的恶意类。
TemplatesImpl
payload如下:
1 | { |
由于com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl类的outputProperties属性类型为Properties因此在反序列化过程中会调用该类的getOutputProperties方法。
1 | public synchronized Properties getOutputProperties() { |
继续跟进newTransformer方法
1 | public synchronized Transformer newTransformer() |
在newTransformer方法中需要实例化一个TransformerImpl类的对象,跟进getTransletInstance()方法
1 | private Translet getTransletInstance() |
跟进defineTransletClasses方法中
1 | private void defineTransletClasses() |
可以看到该方法将会遍历我们传入的_bytecodes数组,执行loader.defineClass方法,而TransletClassLoader类的defineClass方法如下:
1 | Class defineClass(final byte[] b) { |
可见直接实现于ClassLoader类的defineClass方法。查询jdk1.8的文档

可以看到该方法会将我们传入的编码后的class文件加载入jvm。
而我们的恶意类继承于ABSTRACT_TRANSLET,即com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet,因此便会设置_transletIndex为0。再回到我们的getTransletInstance方法中,
1 | AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance(); |
生成了一个我们的恶意类的对象实例,因此导致了我们的恶意类中的代码最后被执行。
这里我们使用的恶意类如下:
1 | package JavaUnser; |