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; |