转载

Fastjson 拒绝服务漏洞分析

漏洞编号

漏洞简介

近日,知名Java Json组件Fastjson被发现存在远程拒绝服务漏洞,攻击者可以通过提交精心构造的JSON数据解析到特定字符触发OOM故障,从而实现拒绝服务攻击。该漏洞影响最新1.2.60之前所有Fastjson版本。

漏洞影响

该漏洞影响Fastjson 1.2.60之前所有版本。

环境搭建

  • Java jdk1.8u121
  • MacOS Mojave 10.14.6

漏洞分析

造成此漏洞的原因有二:

  1. fastjson在处理 /x 转义字符(十六进制数)时没有对转义字符后的字符进行有效性校验
  2. 错误的EOF判断逻辑导致字符串读取到结尾时没有跳出循环

根据漏洞成因和PoC,可以在 com/alibaba/fastjson/parser/JSONLexerBase.class 的5007行 scanStringSingleQuote() 方法中的处理转义字符 x 的分支下断点去跟踪,需要注意的是其判断分支在一个循环中:

Fastjson 拒绝服务漏洞分析

断点命中后,我们发现其试图读取此字符串位置的下一个字符和下下个字符去做一个16进制转10进制的转换:

Fastjson 拒绝服务漏洞分析

此时我们看下 this 变量:

Fastjson 拒绝服务漏洞分析

注意此时 bp 指针为10,和 len 相等。继续跟踪到 com/alibaba/fastjson/parser/JSONScanner.class 的44行 this.next() 方法:

Fastjson 拒绝服务漏洞分析

我们发现其读取下一个字符的逻辑是先将 bp 指针+1然后读取字符。但根据PoC,我们得知下一个字符已经不存在,因此按照其逻辑返回ascii码为26(0x1A)的控制字符。

一个循环执行完成进入下一个循环后,再次执行 this.next() 方法得到控制字符26(0x1A),进入了 if (chLocal == 26) 分支:

Fastjson 拒绝服务漏洞分析

继续跟入 this.isEOF() 判断:

Fastjson 拒绝服务漏洞分析

由于此时bp指针大于字符串长度,错误的EOF判断逻辑导致其返回永远为 false

Fastjson 拒绝服务漏洞分析

于是程序继续运行下一次循环:

Fastjson 拒绝服务漏洞分析

如此循环往复,直至堆溢出,导致 OutOfMemoryError 错误,程序崩溃。

补丁分析

在github上进行 commit diff 对比

可以看到此次提交对处理转义字符 x 的分支中的取值进行了判断,使其符合16进制格式:

Fastjson 拒绝服务漏洞分析

同时修复了错误的 isEOF() 判断逻辑:

Fastjson 拒绝服务漏洞分析

修复建议

升级到最新版本1.2.60。

如果遇到不兼容问题,可以使用如下兼容版本:

1.1.15~1.1.31→1.1.31.sec07

1.1.32~1.1.33→1.1.33.sec06

1.1.34→1.1.34.sec06

1.1.35~1.1.46 →1.1.46.sec06

1.2.3~1.2.7→1.2.7.sec06或1.2.8.sec04

1.2.8→1.2.8.sec06

1.2.9~1.2.29→1.2.29.sec06
原文  http://x3fwy.bitcron.com/post/fastjson_dos
正文到此结束
Loading...