记一次某CMS代码审计
字数 1098 2025-08-26 22:11:40

某CMS文件上传漏洞审计与利用教学文档

1. 漏洞概述

本教学文档详细分析了一个小众OA系统的文件上传漏洞,该漏洞源于系统对用户上传文件的后缀名未做有效过滤,且通过修改参数可控制文件存储位置,最终导致攻击者能够上传恶意文件并执行任意代码。

2. 环境准备

2.1 测试环境

  • 操作系统:Windows 11
  • 开发环境:
    • PhpStudy (包含MySQL)
    • Redis服务
    • IDEA (使用Tomcat 8.0作为服务器)

2.2 初始配置

  1. 将SQL文件导入到phpStudy的MySQL中
  2. 启动Redis服务
  3. 配置好数据库连接环境

3. 漏洞发现过程

3.1 功能点分析

在个人资料处发现图像上传功能,初步测试显示:

  • 系统对上传文件的后缀名和内容均未做校验
  • 返回上传文件的路径和文件名
  • 初始测试无法直接解析上传的文件(文件未实际落地)

3.2 关键上传路径

通过抓包发现上传路径为:/func/upload/uploadImages

4. 代码审计分析

4.1 上传逻辑核心代码

系统根据db参数的值决定文件保存方式:

// 伪代码表示
if (db == GlobalConstant.FILE_UPLOADER_SAVE_FILE) { // 通常为0
    // 保存到文件系统
} else if (db == 1) {
    // 保存到数据库
}

4.2 文件名生成机制

无论哪种保存方式,文件名生成逻辑相同:

String extend = FileUtils.getExtend(fileName); // 获取文件扩展名
String noextfilename = DateUtils.getDataString(DateUtils.SDF_YYYYMMDDHHMMSS) 
                      + StringUtil.random(10); // 时间+10位随机数
String myfilename = noextfilename + "." + extend; // 最终文件名

关键问题:未对extend(文件扩展名)进行任何过滤或检查

4.3 文件保存路径控制

db=0时,文件保存到文件系统:

String realPath = request.getSession().getServletContext().getRealPath("/") 
                + "/upload/" + strYYYYMMDD + "/";
String path = "upload/" + strYYYYMMDD + "/";
File file = new File(realPath);
if (!file.exists()) {
    file.mkdirs(); // 创建目录
}

文件内容直接复制到新文件:

FileCopyUtils.copy(mf.getBytes(), savefile);

5. 漏洞利用步骤

5.1 利用条件

  1. 能够访问文件上传功能
  2. 能够修改db参数

5.2 利用过程

  1. 准备一个JSP Webshell文件(如shell.jsp
  2. 构造上传请求,关键点:
    • db参数值设为0(强制保存到文件系统)
    • 确保文件扩展名为.jsp
  3. 发送上传请求

5.3 预期结果

  • 文件将被保存到Web根目录下的upload/[日期]/目录中
  • 文件名为[时间戳][10位随机数].jsp
  • 可通过返回的路径直接访问并执行Webshell

6. 漏洞修复建议

6.1 输入验证

  1. 对上传文件扩展名进行白名单验证
  2. 检查文件内容是否与扩展名匹配

6.2 安全存储

  1. 避免将上传文件存储在Web可访问目录
  2. 如需Web访问,应配置为不可执行

6.3 参数控制

  1. 不应允许客户端控制文件存储方式(db参数)
  2. 如需不同存储方式,应在服务端逻辑中控制

7. 总结

该漏洞展示了典型的未经验证的文件上传风险,结合以下因素导致严重安全问题:

  1. 未过滤文件扩展名
  2. 客户端可控的关键参数(db
  3. 文件直接保存到Web可访问目录
  4. 未对文件内容进行验证

通过本教学,安全研究人员可以学习到如何审计文件上传功能,识别类似漏洞模式,并采取适当的防护措施。

某CMS文件上传漏洞审计与利用教学文档 1. 漏洞概述 本教学文档详细分析了一个小众OA系统的文件上传漏洞,该漏洞源于系统对用户上传文件的后缀名未做有效过滤,且通过修改参数可控制文件存储位置,最终导致攻击者能够上传恶意文件并执行任意代码。 2. 环境准备 2.1 测试环境 操作系统:Windows 11 开发环境: PhpStudy (包含MySQL) Redis服务 IDEA (使用Tomcat 8.0作为服务器) 2.2 初始配置 将SQL文件导入到phpStudy的MySQL中 启动Redis服务 配置好数据库连接环境 3. 漏洞发现过程 3.1 功能点分析 在个人资料处发现图像上传功能,初步测试显示: 系统对上传文件的后缀名和内容均未做校验 返回上传文件的路径和文件名 初始测试无法直接解析上传的文件(文件未实际落地) 3.2 关键上传路径 通过抓包发现上传路径为: /func/upload/uploadImages 4. 代码审计分析 4.1 上传逻辑核心代码 系统根据 db 参数的值决定文件保存方式: 4.2 文件名生成机制 无论哪种保存方式,文件名生成逻辑相同: 关键问题 :未对 extend (文件扩展名)进行任何过滤或检查 4.3 文件保存路径控制 当 db=0 时,文件保存到文件系统: 文件内容直接复制到新文件: 5. 漏洞利用步骤 5.1 利用条件 能够访问文件上传功能 能够修改 db 参数 5.2 利用过程 准备一个JSP Webshell文件(如 shell.jsp ) 构造上传请求,关键点: 将 db 参数值设为 0 (强制保存到文件系统) 确保文件扩展名为 .jsp 发送上传请求 5.3 预期结果 文件将被保存到Web根目录下的 upload/[日期]/ 目录中 文件名为 [时间戳][10位随机数].jsp 可通过返回的路径直接访问并执行Webshell 6. 漏洞修复建议 6.1 输入验证 对上传文件扩展名进行白名单验证 检查文件内容是否与扩展名匹配 6.2 安全存储 避免将上传文件存储在Web可访问目录 如需Web访问,应配置为不可执行 6.3 参数控制 不应允许客户端控制文件存储方式( db 参数) 如需不同存储方式,应在服务端逻辑中控制 7. 总结 该漏洞展示了典型的未经验证的文件上传风险,结合以下因素导致严重安全问题: 未过滤文件扩展名 客户端可控的关键参数( db ) 文件直接保存到Web可访问目录 未对文件内容进行验证 通过本教学,安全研究人员可以学习到如何审计文件上传功能,识别类似漏洞模式,并采取适当的防护措施。