#概述
最近Fastjson反序列化Bypass绕过AutoType的漏洞越来越多,趁着国庆休息时间,把历年来曝光的3个Fastjson RCE漏洞进行了分析,把过程笔记整理下,本来想一篇blog文但篇幅越写越多,考虑到阅读体验就做了一个Fastjson反序列化漏洞的系列文章,大致目录如下:
[1]. Fastjson反序列化漏洞系列1-什么是fastjson反序列化?
[2]. Fastjson反序列化漏洞系列2-如何构造fastjson反序列化RCE漏洞Poc?
[3]. Fastjson反序列化漏洞系列3-fastjson <=1.2.24反序列化RCE漏洞(CNVD-2017-02833)原理分析及Poc构造
[4]. Fastjson反序列化漏洞系列4-fastjson <1.2.48反序列化RCE漏洞(CNVD-2019-22238)原理分析及Poc构造
[5]. Fastjson反序列化漏洞系列5-fastjson <=1.2.60反序列化RCE漏洞(CNVD-2019-32498)原理分析及Poc构造
(大概4-5篇这样,后面陆续更新,感兴趣的小伙伴可以关注收藏作者Freebuf主页https://www.freebuf.com/author/%E6%9C%A8%E5%AD%90)
[1].Fastjson反序列化漏洞系列1-什么是fastjson反序列化?
#什么是Fastjson?
Fastjson是Alibaba开发的Java语言编写的高性能JSON库(https://github.com/alibaba/fastjson) 采用“假定有序快速匹配”的算法,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。Fastjson接口简单易用,广泛使用在缓存序列化、协议交互、Web输出、Android客户端等,目前有2个主要接口toJsonString和parseObject来分别实现序列化和反序列化。
#Fastjson反序列化框架
Fastjson反序列化框架图
在Fastjson反序列化框架中JSON是门面类,提供一些静态方法,如parse,parseObject,其主要功能都是在DefaultJSONParser类中实现的。DefaultJSONParser引用了ParserConfig类,该类主要保存一些相关配置信息。也引用了JSONLexerBase类用来处理字符分析,序列化用到的是JavaBeanSerializer类,而反序列化用到的是JavaBeanDeserializer类。
#Demo演示FastJson反序列化实现过程
1.定义User.java,代码如下:(该代码已经发布到Github,地址见文末)
//定义用户类
public class User {
private Longid;
privateString name;
//增加get/set方法
public LonggetId() { return id; }
public voidsetId(Long id) { this.id = id; }
publicString getName() { return name; }
public voidsetName(String name) { this.name = name; }
}
2.定义测试Test.java,代码如下:(该代码已经发布到Github,地址见文末)
importcom.alibaba.fastjson.JSON;
//定义测试类,
public class Test {
publicstatic void main(String[] args) {
UserguestUser = new User();
guestUser.setId(1L);
guestUser.setName("guest");
//将java对象序列化为json对象
StringjsonString1 = JSON.toJSONString(guestUser);
System.out.println("Json对象:"+jsonString1);
//将json反序列化为java对象
StringjsonString2="{\"id\":2,\"name\":\"root\"}";
Useruser = JSON.parseObject(jsonString2,User.class);
System.out.println("Java对象:"+user);
//打印变量类型
System.out.println(user.getClass().getTypeParameters());
}
}
运行
最后输出如下
jsonString1--Json对象:{"id":1,"name":"guest"}
user--Java对象:User@7ab2bfe1
user的类型为[Ljava.lang.reflect.TypeVariable;@497470ed
#动态调试理解调用链
还是利用上面的Demo进行动态调试
在String jsonString1 = JSON.toJSONString(guestUser); 和User user = JSON.parseObject(jsonString2,User.class); 处设置断点
1.动态调试理解这个序列化过程
先调用/com/alibaba/fastjson/JSON.class的toJSONString对象
com/alibaba/fastjson/serializer/SerializeWriter.class的SerializeWriter对象
读取SerializeConfig 配置
最后调用 com/alibaba/fastjson/serializer/JavaBeanSerializer.class类进行序列化
com/alibaba/fastjson/JSON.class 的toJSONString
2.动态调试理解反序列化过程
先调用com/alibaba/fastjson/JSON.class的parseObject 对象
跳到com/alibaba/fastjson/parser/DefaultJSONParser.class 的parseObject对象
com/alibaba/fastjson/parser/ParserConfig.class的ObjectDeserializer 对象
最后调用 com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.class类进行反序列化
#造成远程命令执行的原因?
Fastjson反序列化的Gadget需要无参默认构造方法或者注解指定构造方法并添加相应参数。使用Feature.SupportNonPublicField才能打开非公有属性的反序列化处理,@type可以指定反序列化任意类调用其set,get,is方法,并且由于反序列化的特性,我们可以通过目标类的set方法自由的设置类的属性值。常见的攻击流程是这样的:攻击者准备rmi服务和web服务,将rmi绝对路径注入到lookup方法中,受害者JNDI接口会指向攻击者控制rmi服务器,JNDI接口向攻击者控制web服务器远程加载恶意代码,执行构造函数形成RCE。
本文用到的Demo源代码已经在Github发布,感兴趣的小伙伴可以自己研究调试
地址如下:
本节到此结束,下一节是
[2]. Fastjson反序列化漏洞系列2-如何构造fastjson反序列化RCE漏洞Poc?
敬请期待,感兴趣的小伙伴可以关注收藏作者Freebuf主页 (https://www.freebuf.com/author/%E6%9C%A8%E5%AD%90)
免责声明:
本文中提到的漏洞利用Poc和脚本工具仅限于研究学习使用,请遵守《网络安全法》等相关法律法规。
参考: