最近在看内网相关的东西,好东西都写本地了没发出来,被4riH04X师傅叫去看个洞,浅写一下🤔
CVE-2023-51074 是一个影响 json-path 组件的安全漏洞,涉及基于栈的缓冲区溢出问题,可能导致拒绝服务(DoS)攻击。以下是该漏洞的详细分析:
1.漏洞背景
-
组件说明:
json-path 是一个用于解析和查询 JSON 数据的库,广泛应用于 Java 生态系统中,例如在 Apache Kafka、Spring Boot 等框架中处理 JSON 配置或数据流。 -
漏洞本质:
该漏洞存在于Criteria.parse
方法中,攻击者可通过构造特定的 JSON 查询表达式触发栈溢出,导致进程崩溃或拒绝服务。
2.漏洞原理
-
触发条件:
当Criteria.parse
方法处理包含深度嵌套结构或复杂递归逻辑的 JSON 查询表达式时,未对解析深度或递归调用进行有效限制,导致栈空间耗尽。 -
攻击方式:
攻击者发送恶意构造的 JSON 查询请求,利用嵌套层数超过系统栈容量的表达式,触发栈溢出异常,使服务崩溃。
3.影响范围
-
受影响版本:
json-path
版本 >= 2.2.0,< 2.9.0 -
受影响系统:
使用未修复版本 json-path 的应用,尤其是依赖该库处理 JSON 查询的中间件或服务(如 Apache Camel、Kafka Connect 等)
4.漏洞复现&分析
给一段exp
package org.example;
import com.jayway.jsonpath.Criteria;
public class CriteriaFuzzerParse {
public static void main(String[] args) {
try {
parseCriteria();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void parseCriteria() throws Exception {
// 原始测试用例的解析逻辑
Criteria result = Criteria.parse("@[\"\",/\\");
}
}
跑出来结果,成功栈溢出
跟一下调用过程
走到readNextToken
进来的时候char为[
又回到了readNextToken,但这时候的char变成了@
走到default调用readPropertyOrFunctionToken
再次回到readNextToken,而这时候的char又变成了[
最终
PathCompiler#readNextToken与PathCompiler#readBracketPropertyToken
PathCompiler#readNextToken与PathCompiler#readPropertyOrFunctionToken互相依次递归调用
5.关键解读
在 JsonPath 的语法解析器中,readBracketPropertyToken
和 readPropertyOrFunctionToken
是用于解析 JSONPath 表达式中不同部分的两个关键方法。
示例解析流程 示例 1:
示例 2:
代码暴露的关键差异
|
---|
重点来看PathCompiler#readBracketPropertyToken的这部分
endPosition是3,即@["",/\的第四个字符"
跟进indexOfNextSignificantChar
最后readPosition为4,即@["",/\的第五个字符,
,不等于],indexOfNextSignificantChar返回-1
但代码逻辑还对indexOfNextSignificantChar的返回值加了1,所以最后拿到的c为0
于是下一轮readNextToken去读@["",/\的第一个字符@
走到PathCompiler#readPropertyOrFunctionToken
@的下一个字符是[,走进图里的分支,设置endPosition为1
最终postion为1,下一轮读到 @["",/\的第二个字符[
从此循环递归调用
6.漏洞修复
https://github.com/json-path/JsonPath/commit/71a09c1193726c010917f1157ecbb069ad6c3e3b
可以看到在indexOfNextSignificantChar处理完后返回了原数据,而没有+1,避免找不到]的时候去重读第一个字符,防止造成递归调用。