云时空ERP系统任意文件上传漏洞分析
字数 1622 2025-08-23 18:31:17

云时空ERP系统任意文件上传漏洞分析教学文档

一、漏洞概述

本教学文档详细分析云时空ERP系统中存在的任意文件上传漏洞,该漏洞允许攻击者绕过安全限制上传任意文件到服务器,可能导致远程代码执行(RCE)等严重后果。

二、系统架构分析

1. 核心路由配置

系统使用WEB-INF/web.xml配置文件定义Servlet组件和过滤器:

  • 基于Spring框架进行Web开发
  • 整合Apache Shiro进行安全控制
  • 配置了字符编码和跨域资源共享(CORS)处理

2. 安全控制机制

系统主要安全控制通过Shiro实现:

<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

关键点:

  • shiroFilter应用于所有URL(/*)
  • 使用DelegatingFilterProxy代理到Spring上下文中定义的bean
  • 自定义的CustomShiroFilterFactoryBean处理潜在风险字符

3. Shiro权限配置

spring-context-shiro.xml中定义了权限规则:

/servlet/fileupload/gpy* = anon

表示/servlet/fileupload/gpy*路径不需要认证即可访问,这是漏洞存在的关键配置。

三、漏洞详细分析

1. 文件上传处理流程

  1. 请求处理

    • 使用HttpServletRequest读取请求数据
    • 处理multipart/form-data格式数据
    • DataInputStream in = new DataInputStream(request.getInputStream())直接从输入流读取数据
  2. 文件名提取

    if (s.indexOf("filename=") == -1) {
        // 表单字段处理
    } else {
        int pos22 = s.indexOf("filename=");
        String fileFormName = s.substring(pos2, pos22 - 3);
        String s3 = s.substring(pos22 + "filename=".length() + 1);
        // 无文件名和后缀过滤
        out.print("fileRealName=" + s5 + "");
    }
    
    • 直接提取文件名,无任何过滤
    • 将原始文件名直接写入响应
  3. 文件存储

    String saveDirectoryPath = curProjectPath + "/uploads" + uploadFolderName + curDate + "/";
    File f = new File(saveDirectoryPath + File.separator + s5);
    DataOutputStream fileout = new DataOutputStream(new FileOutputStream(f));
    fileout.write(b3, 0, b3.length - 1);
    
    • 存储路径:web应用根目录/uploads/pics/服务器日期/
    • 直接使用用户提供的文件名保存文件
    • 无文件内容检查

2. 漏洞关键点

  1. 认证绕过

    • Shiro配置/servlet/fileupload/gpy* = anon允许匿名访问
  2. 无文件过滤

    • 未检查文件扩展名(尽管定义了extensionPermit但未使用)
    • 未对文件名进行安全处理
    • 未验证文件内容类型
  3. 路径可预测

    • 存储路径包含服务器日期,但日期通过out.print("date=" + curDate)暴露
    • 攻击者可轻松构造完整访问路径

四、漏洞复现步骤

  1. 构造恶意请求

    • /servlet/fileupload/gpy路径发送POST请求
    • 内容类型为multipart/form-data
    • 包含恶意文件(如webshell.jsp)
  2. 获取存储信息

    • 从响应中获取date参数(服务器日期)
    • 从响应中获取fileRealName(原始文件名)
  3. 访问上传文件

    • 构造访问路径:http://target/uploads/pics/[date]/[filename]
    • 验证文件是否可访问

五、修复建议

  1. 权限控制

    • 修改Shiro配置,要求认证后才能上传文件
    /servlet/fileupload/gpy* = authc
    
  2. 文件过滤

    // 定义允许的扩展名
    private static final Set<String> ALLOWED_EXTENSIONS = Set.of("jpg", "png", "gif");
    
    // 验证文件扩展名
    String extension = FilenameUtils.getExtension(filename).toLowerCase();
    if (!ALLOWED_EXTENSIONS.contains(extension)) {
        throw new IllegalArgumentException("不允许的文件类型");
    }
    
  3. 文件名处理

    • 使用UUID生成随机文件名
    • 保留原始扩展名
    String safeFilename = UUID.randomUUID() + "." + extension;
    
  4. 内容验证

    • 验证文件魔数(magic number)
    • 对图片文件进行图像解析验证
  5. 存储隔离

    • 将上传文件存储在web根目录之外
    • 通过控制器方法提供文件下载
  6. 路径隐藏

    • 不返回完整的存储路径信息
    • 使用文件ID或令牌机制访问文件

六、深入理解

  1. 漏洞成因本质

    • 认证与授权分离(Shiro配置问题)
    • 信任边界失效(直接使用用户输入作为文件路径)
    • 缺乏深度防御(多层验证缺失)
  2. 攻击面扩展

    • 结合路径遍历可实现更灵活的存储位置控制
    • 结合SMB配置可能实现网络渗透
    • 可发展为持久化后门
  3. 安全开发要点

    • 最小权限原则
    • 输入验证与输出编码
    • 安全默认配置
    • 不信任任何用户输入

本教学文档详细分析了云时空ERP系统的文件上传漏洞,从系统架构到漏洞细节,再到修复方案,提供了全面的技术视角。理解此类漏洞有助于开发更安全的文件上传功能。

云时空ERP系统任意文件上传漏洞分析教学文档 一、漏洞概述 本教学文档详细分析云时空ERP系统中存在的任意文件上传漏洞,该漏洞允许攻击者绕过安全限制上传任意文件到服务器,可能导致远程代码执行(RCE)等严重后果。 二、系统架构分析 1. 核心路由配置 系统使用 WEB-INF/web.xml 配置文件定义Servlet组件和过滤器: 基于Spring框架进行Web开发 整合Apache Shiro进行安全控制 配置了字符编码和跨域资源共享(CORS)处理 2. 安全控制机制 系统主要安全控制通过Shiro实现: 关键点: shiroFilter 应用于所有URL( /* ) 使用 DelegatingFilterProxy 代理到Spring上下文中定义的bean 自定义的 CustomShiroFilterFactoryBean 处理潜在风险字符 3. Shiro权限配置 在 spring-context-shiro.xml 中定义了权限规则: 表示 /servlet/fileupload/gpy* 路径不需要认证即可访问,这是漏洞存在的关键配置。 三、漏洞详细分析 1. 文件上传处理流程 请求处理 : 使用 HttpServletRequest 读取请求数据 处理 multipart/form-data 格式数据 DataInputStream in = new DataInputStream(request.getInputStream()) 直接从输入流读取数据 文件名提取 : 直接提取文件名,无任何过滤 将原始文件名直接写入响应 文件存储 : 存储路径: web应用根目录/uploads/pics/服务器日期/ 直接使用用户提供的文件名保存文件 无文件内容检查 2. 漏洞关键点 认证绕过 : Shiro配置 /servlet/fileupload/gpy* = anon 允许匿名访问 无文件过滤 : 未检查文件扩展名(尽管定义了 extensionPermit 但未使用) 未对文件名进行安全处理 未验证文件内容类型 路径可预测 : 存储路径包含服务器日期,但日期通过 out.print("date=" + curDate) 暴露 攻击者可轻松构造完整访问路径 四、漏洞复现步骤 构造恶意请求 : 向 /servlet/fileupload/gpy 路径发送POST请求 内容类型为 multipart/form-data 包含恶意文件(如webshell.jsp) 获取存储信息 : 从响应中获取 date 参数(服务器日期) 从响应中获取 fileRealName (原始文件名) 访问上传文件 : 构造访问路径: http://target/uploads/pics/[date]/[filename] 验证文件是否可访问 五、修复建议 权限控制 : 修改Shiro配置,要求认证后才能上传文件 文件过滤 : 文件名处理 : 使用UUID生成随机文件名 保留原始扩展名 内容验证 : 验证文件魔数(magic number) 对图片文件进行图像解析验证 存储隔离 : 将上传文件存储在web根目录之外 通过控制器方法提供文件下载 路径隐藏 : 不返回完整的存储路径信息 使用文件ID或令牌机制访问文件 六、深入理解 漏洞成因本质 : 认证与授权分离(Shiro配置问题) 信任边界失效(直接使用用户输入作为文件路径) 缺乏深度防御(多层验证缺失) 攻击面扩展 : 结合路径遍历可实现更灵活的存储位置控制 结合SMB配置可能实现网络渗透 可发展为持久化后门 安全开发要点 : 最小权限原则 输入验证与输出编码 安全默认配置 不信任任何用户输入 本教学文档详细分析了云时空ERP系统的文件上传漏洞,从系统架构到漏洞细节,再到修复方案,提供了全面的技术视角。理解此类漏洞有助于开发更安全的文件上传功能。