参考几位师傅的文章复现分析下fastjson的漏洞
0x01 序列化和反序列化
为了方便修改fastjson版本,利用maven构建项目,
直接用了rai4over师傅的源码,User()的成员及其属性如下:
序列化
- 非自省的序列化:
JSON.toJSONString(Object object)
1 | import com.alibaba.fastjson.JSON; |
只要存在get方法(不管是public还是private)都被调用。
1 | { |
可以发现除了private属性而且不存在对应的get方法的成员外,其他的成员均被序列化。
- 自省的序列化:
toJSONString(Object object, SerializerFeature... features)
1 | import com.alibaba.fastjson.JSON; |
只要存在get方法(不管是public还是private)都被调用。与非自省相同。
1 | { |
与非自省的区别是增加了@type
字段,可以得到对象的类型。
反序列化
- 反序列化分三种,分别是
parseObject(String text, Class<T> clazz)
、JSONObject parseObject(String text)
、parse(String text)
。反序列化时要把User.java中的构造函数注释掉。
1 | import com.alibaba.fastjson.JSON; |
JSON.parseObject()指定类,非自省
只要存在set方法(不管是public还是private)都被调用。额外调用了
getprop2_2();//private且有get
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17User {
name1 = 'mount4in1', name2 = 'mount4in2', name3 = 'mount4in3', name4 = 'mount4in4', age1 = 'a1', age2 = 'null', age3 = 'a3', age4 = 'null', prop1_1 = {
prop1_1 = 1 _1
}, prop1_2 = {
prop1_2 = 1 _2
}, prop1_3 = {
prop1_3 = 1 _3
}, prop1_4 = {
prop1_4 = 1 _4
}, prop2_1 = {
prop2_1 = 2 _1
}, prop2_2 = {
prop2_2 = 2 _2
}, prop2_3 = {
prop2_3 = 2 _3
}, prop2_4 = null
}public属性或含有set方法的成员都被赋值,private属性而且没有set方法的的成员赋值为null,但是这里prop2_2被赋值了,不知道什么原因。
JSON.parseObject()自省
所有的set和get方法都被调用,getProp2_2调用了两次。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25{
"prop1_3": {
"prop1_3": "1_3"
},
"prop2_2": {
"prop2_2": "2_2"
},
"prop1_4": {
"prop1_4": "1_4"
},
"name4": "mount4in4",
"prop1_1": {
"prop1_1": "1_1"
},
"name3": "mount4in3",
"prop1_2": {
"prop1_2": "1_2"
},
"prop2_1": {
"prop2_1": "2_1"
},
"name2": "mount4in2",
"name1": "mount4in1",
"age1": "a1"
}这里public属性的成员都被赋值,private属性的的只有age1和prop2_1被赋值。
JSON.parse()
只要存在set方法(不管是public还是private)都被调用。额外调用了
getprop2_2();//private且有get
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17User {
name1 = 'mount4in1', name2 = 'mount4in2', name3 = 'mount4in3', name4 = 'mount4in4', age1 = 'a1', age2 = 'null', age3 = 'a3', age4 = 'null', prop1_1 = {
prop1_1 = 1 _1
}, prop1_2 = {
prop1_2 = 1 _2
}, prop1_3 = {
prop1_3 = 1 _3
}, prop1_4 = {
prop1_4 = 1 _4
}, prop2_1 = {
prop2_1 = 2 _1
}, prop2_2 = {
prop2_2 = 2 _2
}, prop2_3 = {
prop2_3 = 2 _3
}, prop2_4 = null
}public属性或含有set方法的成员都被赋值,private属性而且没有set方法的的成员赋值为null,但是这里prop2_2被赋值了,不知道什么原因。
ps:可以通过传递Feature.SupportNonPublicField
来对没有set方法的private属性成员赋值。
1 | import com.alibaba.fastjson.JSON; |
1 | User { |