接着昨天的来说,由于fastjson调试起来过程比较复杂,在这里直接看关键点:首先会获取字符串的第一对引号中的内容
如果内容为@type就会加载下一对引号中的类
?
?
在JavaBeanInfo.class中会获取类中所有详细详细 在这里匹配以set开头的方法
methodName.length()?>=?4?&&?
!Modifier.isStatic(method.getModifiers())?&&?
(method.getReturnType().equals(Void.TYPE)?||?
method.getReturnType().equals(method.getDeclaringClass())))
?函数名长度大于等于4非静态方法,以get开头且第4个字母为大写,无参数,返回值类型继承自Collection或Map或AtomicBoolean,或Atomiclnteger或AtomicLon的方法
methodName.length()?>=?4?&&?
!Modifier.isStatic(method.getModifiers())?&&?
methodName.startsWith("get")?&&?
Character.isUpperCase(methodName.charAt(3))?&&?
method.getParameterTypes().length?==?0?&&?
(Collection.class.isAssignableFrom(method.getReturnType())?||?
Map.class.isAssignableFrom(method.getReturnType())?||?
AtomicBoolean.class?==?method.getReturnType()?||?
AtomicInteger.class?==?method.getReturnType()?||?
AtomicLong.class?==?method.getReturnType()))
?其实本质就是fastjson会利用反序列化通过无参构造创建一个对象,不通过setter或getter方法进行赋值与输出操作 因此我们只需要找到满足条件的类就行,这里一般利用的是 TemplatesImpl链来加载字节码,从而rce等操作 下面我们来证明一下我们的观点 在setter方法中添加一段命令执行的代码
package?com.naihe;
public?class?User?{
????private?String?name;
????private?int?age;
????public?User()?{}
????public?User(String?name,?int?age)?{
????????this.name?=?name;
????????this.age?=?age;
????}
????public?String?getName()?{
????????return?name;
????}
????public?void?setName(String?name)?{
????????this.name?=?name;
????}
????public?int?getAge()?{
????????return?age;
????}
????public?void?setAge(int?age)?{
????????this.age?=?age;
????}
}
Demo:
package?com.naihe;
import?com.alibaba.fastjson.JSONObject;
public?class?Demo1?{
????public?static?void?main(String[]?args)?{
????????String?str?=?"{\"@type\":\"com.naihe.User\",\"age\":1000,\"name\":\"老李\"}";
????????Object?obj1?=?JSONObject.parse(str);
????????
????}
}
?