赞
踩
Fastjson
是一个Java语言编写的高性能功能完善的JSON库。
FastJson
高性能的原理是自己写了一套ASM框架,而不是用反射来进行操作,所以FastJson
的处理速度,比市面上常见的json处理组件要快
FastJson
的漏洞,主要是围绕setter
与getter
方法
fastjson
中产生漏洞的根本原因在于其 autoType
机制,以及针对于 autoType
机制做的checkAutoType
检测防御机制。
1.2.24及以下 主要是因为,没有对序列化的类做校验,导致漏洞产生
1.2.25-1.2.41增加了黑名单限制,更改autoType
默认为关闭选项。
1.2.42版本是对1.2.41及以下版本的黑名单绕过,代码内更新字符串黑名单为hash方式
1.2.43版本是对1.2.42及以下版本的黑名单绕过
1.2.44-1.2.45版本1.2.43版本黑名单无法绕过,寻找新的利用链进行利用
1.2.47版本 利用fastjson
处理Class
类时的操作,将恶意类加载到缓存中,实现攻击
1.2.62-1.2.67版本 Class
不会再往缓存中加载恶意类,寻找新的利用链进行突破
1.2.68版本,使用期望类AutoCloseable
来绕过fastjson
校验
1.2.72-1.2.80使用期望类Throwable的子类,进行饶过
@RequestMapping("/fastjson")
public String fastjson(@RequestBody String ObjName) {
try {
JSONObject jsonObject = JSONObject.parseObject(ObjName);
String type = jsonObject.toJSONString();
return type;
} catch (Exception e) {
return e.toString();
}
}
package com.example.fastjson_demo.Example; import java.io.Closeable; import java.io.IOException; public class exec implements Closeable { public String exec; public String getExec1() { return exec1; } public void setExec1(String exec1) { this.exec1 = exec1; } public String exec1; public String getExec() { return exec; } public void setExec(String exec) throws IOException { this.exec = exec; Runtime.getRuntime().exec(this.exec); } @Override public void close() { } }
{
"@type":"com.example.fastjson_demo.Example.exec",
"exec":"calc",
"exec1":"calc1"
}
com.alibaba.fastjson.JSON#parseObject(java.lang.String)
com.alibaba.fastjson.JSON#parse(java.lang.String)
com.alibaba.fastjson.JSON#parse(java.lang.String, int)
传入了一个fastjson分析器实例,用来检查或分析后续操作。
com.alibaba.fastjson.JSON#parse(java.lang.String, com.alibaba.fastjson.parser.ParserConfig, int)
在这里,开始进行Json字符串解析,跟进DefaultJSONParser类看一下。
com.alibaba.fastjson.parser.DefaultJSONParser#DefaultJSONParser()
JSONScanner
是对JSON
字符串进行处理并分析,JSONScanner extends JSONLexerBase
JSONLexerBase implements JSONLexer
所以在DefaultJSONParser
的构造方法中,获取的为JSONLexer
对象
com.alibaba.fastjson.parser.DefaultJSONParser#DefaultJSONParser()
在这里开始对JSON
字符串进行初始化操作。
执行next()
方法将递增字符串下标,更新this.ch
参数,执行一次next()
更新一次下标,同时也更新this.ch
。
在之前JSONScanner
初始化时,已经执行过next()
,所以lexer.getCurrent()
在此直接拿到的就是JSON字符串的第一个值。
如果json
的字符串为{
形式,token
就为12,如果json
的字符串为[
形式,就标记token
为14
至此 , 传入的JSON字符串已经初始化完成 。
com.alibaba.fastjson.parser.DefaultJSONParser#parse()
开始分析并获取Json中的内容
com.alibaba.fastjson.parser.DefaultJSONParser#parse(java.lang.Object)
token
,标记值为12
,继续跟进
传入的JSONObject
如果为true
的话,会使用LinkedHashMap(有序)
,如果传入的false
的话会使用HashMap(无序)
。
com.alibaba.fastjson.parser.DefaultJSONParser#parseObject(java.util.Map, java.lang.Object)
因为LinkedHashMap
与HashMap
都是为Map
的实现类,所以在此转为Map
仍可使用
token为12
简单来说,这里的逻辑就是, 检查你的json
字符串是否合规,合规的话,取出值, 检查key
的名称是否为JSON.DEFAULT_TYPE_KEY 也就是 @type
lexer.scanSymbol(this.symbolTable, '"');
这段代码的意思为从当前字符串开始,获取,到下一个"的中间的值,也就是指定闭合符,获取闭合符中的内容并返回。
然后将@type
的值给到autoType
进行检查,检查通过,继续进行下一个检查
当JSONScanner
初始化的Map
为null
时, 也就是还没有向map
内进行添加操作时
简单说就是去系统内获取Deserializer
, 获取不到系统内的Deserializer
, 没有对应的, 就会去获取当前类的注解,如果注解依然不存在的话
… … … …
如果以上匹配都不通过的话, 则会匹配是否为Java的一些工具类或者是否为三方类
此处略过一万字, 如果fastjson
的@type
的值,不在以上这些限定的类或其他东西中,则create创建一个出来,然后加入到deserializer
中
com.alibaba.fastjson.parser.ParserConfig#createJavaBeanDeserializer
看一下这边是怎么实现的,跟进createJavaBeanDeserializer
方法
大概解释一下 这里一些if的意思
首先对是否开启asm功能进行判断
如果开启了,那么这个要被序列化的类,是否有注解
然后获取类的信息,匹配父类是否有注解
然后判断里面的泛型变量, 如果存在的话 关闭asm功能
然后判断asm工厂类是否为null,并检查他们的上一级关系,是否与ASMClassLoader相同
然后经过上面的步骤后,判断asm是否还为开启状态
然后检查包和类地址的合法性
然后检查类地址是否为接口类型
然后根据clazz
和propertyNamingStrategy
生成beaninfo
又经过一堆判断之后,调用asm工厂类生成处理类
com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory#createJavaBeanDeserializer
其实看到这里已经比较吃力了,没有系统学习过ASM,建议大家去看Lucifaer师傅的文章https://paper.seebug.org/994/讲的很清晰
跟踪到
com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#JavaBeanDeserializer()
这个类,大概就是将clazz
中的一些信息,转换为FieldDeserializer
存储到sortedFieldDeserializers
转换之后
然后执行到了JavaBeanDeserializer
下的deserialze
方法
com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer#deserialze()
对@type的key进行处理
然后用过DefaultFieldDeserializer的parseField方法进行操作,执行setValue进行赋值操作
setValue()
,然后通过反射,操作方法,然后执行,导致漏洞产生
这样就导致了Fastjson
命令执行。
fastjson 1.2.24-1.2.67 漏洞分析,附Poc分析
https://github.com/Lonely-night/fastjsonVul
https://github.com/safe6Sec/Fastjson
https://www.freebuf.com/news/347174.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。