致远OA鉴权浅析与wpsAssistServlet 任意文件上传漏洞分析
字数 1596 2025-08-24 07:48:22

致远OA鉴权分析与wpsAssistServlet任意文件上传漏洞深度解析

一、致远OA系统路由分析

1.1 核心路由配置文件

致远OA系统的核心路由配置位于:

/ApacheJetspeed/webapps/seeyon/WEB-INF/web.xml

该文件主要包含:

  • Servlet组件定义
  • 过滤器配置
  • 主要权限校验由CTPSecurityFilter过滤器实现

1.2 Spring框架路由配置

系统使用Spring框架,路由通过配置文件定义而非注解,配置文件位于:

/ApacheJetspeed/webapps/seeyon/WEB-INF/cfgHome/spring/

二、鉴权机制深度分析

2.1 CTPSecurityFilter过滤器

核心鉴权逻辑在doFilter方法中,关键流程如下:

  1. 调用authenticate方法进行用户认证
  2. 认证通过后检查URL是否在保护名单中

2.2 authenticate方法分析

该方法会根据请求URI选择不同的认证策略:

if (isSpringController(uri, req)) {
    // Spring控制器认证
} else if (tokenAuthenticator.validate(uri, req)) {
    // Token认证
} else if (isRest(uri, req)) {
    // REST API认证
} else if (isV3xAjax(uri, req)) {
    // V3xAjax认证
} else if (isSOAP(uri, req)) {
    // SOAP认证
} else if (isServlet(uri, req)) {
    // Servlet认证
} else if (isJSP(uri, req)) {
    // JSP认证
} else if (webOfficeAuthenticator.validate(uri, req)) {
    // WebOffice认证
} else {
    // 默认认证
    result.setAuthenticator(defaultAuthenticator);
    result.authenticate(req, resp);
}

2.3 Servlet认证关键点

isServlet判断调用ServletAuthenticator类的accept方法:

  1. 首先检查URI是否以".psml"结尾,是则直接返回true
  2. 否则检查URI是否在servlets集合中

重要发现

  • servlets集合中的Servlet数量少于web.xml中定义的Servlet
  • 未在servlets集合中的Servlet会进入defaultAuthenticator
  • defaultAuthenticator不做任何校验,所有URI都被视为有效

三、wpsAssistServlet任意文件上传漏洞分析

3.1 漏洞入口

wpsAssistServlet存在于web.xml但不在servlets集合中,因此:

  • 绕过鉴权直接进入defaultAuthenticator
  • 无需认证即可访问

3.2 漏洞触发流程

  1. 请求处理

    • 从请求中获取flag参数决定操作类型
    • flag=save时执行saveFile方法
  2. saveFile方法分析

    String fileId = request.getHeader("fileId");
    if (canGetLock(Long.valueOf(fileId))) {
        oaSaveFile(request, response);
    }
    
    • 从请求头获取fileId参数
    • 检查locksMap中是否存在对应fileId的锁定标记
    • 存在则调用oaSaveFile方法保存文件
  3. 文件上传漏洞

    • oaSaveFile方法使用realFileType参数构造文件路径
    • 未对realFileType进行有效过滤
    • 可通过../实现目录穿越
    • 可上传JSP文件至Web可执行目录

3.3 漏洞利用条件

  1. 构造请求使flag=save
  2. 在请求头中包含有效的fileId参数
  3. fileId需存在于系统的locksMap
  4. 通过realFileType参数构造恶意路径

四、漏洞复现与防御建议

4.1 漏洞复现步骤

  1. 构造HTTP请求访问wpsAssistServlet
  2. 设置flag=save
  3. 添加包含有效fileId的请求头
  4. 通过realFileType参数实现路径穿越
  5. 上传包含恶意代码的JSP文件

4.2 防御建议

  1. 补丁修复

    • 升级至官方最新安全版本
    • wpsAssistServlet加入servlets集合
  2. 临时缓解措施

    <!-- 在web.xml中移除或限制wpsAssistServlet访问 -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Restricted</web-resource-name>
            <url-pattern>/wpsAssistServlet</url-pattern>
        </web-resource-collection>
        <auth-constraint/>
    </security-constraint>
    
  3. 代码层面修复

    • oaSaveFile方法中添加路径规范化检查
    • 限制上传文件类型,禁止.jsp等可执行文件
    • 实现更严格的fileId验证机制

五、技术总结

  1. 鉴权绕过根源

    • servlets集合与web.xml配置不一致
    • defaultAuthenticator缺乏有效验证
  2. 文件上传漏洞关键

    • 未过滤的realFileType参数
    • 缺乏上传文件类型检查
    • 缺乏路径规范化处理
  3. 安全开发建议

    • 保持权限校验的一致性
    • 对所有用户输入进行严格验证
    • 实现最小权限原则
    • 定期进行安全审计

参考资源

致远OA鉴权分析与wpsAssistServlet任意文件上传漏洞深度解析 一、致远OA系统路由分析 1.1 核心路由配置文件 致远OA系统的核心路由配置位于: 该文件主要包含: Servlet组件定义 过滤器配置 主要权限校验由 CTPSecurityFilter 过滤器实现 1.2 Spring框架路由配置 系统使用Spring框架,路由通过配置文件定义而非注解,配置文件位于: 二、鉴权机制深度分析 2.1 CTPSecurityFilter过滤器 核心鉴权逻辑在 doFilter 方法中,关键流程如下: 调用 authenticate 方法进行用户认证 认证通过后检查URL是否在保护名单中 2.2 authenticate方法分析 该方法会根据请求URI选择不同的认证策略: 2.3 Servlet认证关键点 isServlet 判断调用 ServletAuthenticator 类的 accept 方法: 首先检查URI是否以".psml"结尾,是则直接返回true 否则检查URI是否在 servlets 集合中 重要发现 : servlets 集合中的Servlet数量少于web.xml中定义的Servlet 未在 servlets 集合中的Servlet会进入 defaultAuthenticator defaultAuthenticator 不做任何校验,所有URI都被视为有效 三、wpsAssistServlet任意文件上传漏洞分析 3.1 漏洞入口 wpsAssistServlet 存在于web.xml但不在 servlets 集合中,因此: 绕过鉴权直接进入 defaultAuthenticator 无需认证即可访问 3.2 漏洞触发流程 请求处理 : 从请求中获取 flag 参数决定操作类型 当 flag=save 时执行 saveFile 方法 saveFile方法分析 : 从请求头获取 fileId 参数 检查 locksMap 中是否存在对应 fileId 的锁定标记 存在则调用 oaSaveFile 方法保存文件 文件上传漏洞 : oaSaveFile 方法使用 realFileType 参数构造文件路径 未对 realFileType 进行有效过滤 可通过 ../ 实现目录穿越 可上传JSP文件至Web可执行目录 3.3 漏洞利用条件 构造请求使 flag=save 在请求头中包含有效的 fileId 参数 该 fileId 需存在于系统的 locksMap 中 通过 realFileType 参数构造恶意路径 四、漏洞复现与防御建议 4.1 漏洞复现步骤 构造HTTP请求访问 wpsAssistServlet 设置 flag=save 添加包含有效 fileId 的请求头 通过 realFileType 参数实现路径穿越 上传包含恶意代码的JSP文件 4.2 防御建议 补丁修复 : 升级至官方最新安全版本 将 wpsAssistServlet 加入 servlets 集合 临时缓解措施 : 代码层面修复 : 在 oaSaveFile 方法中添加路径规范化检查 限制上传文件类型,禁止.jsp等可执行文件 实现更严格的 fileId 验证机制 五、技术总结 鉴权绕过根源 : servlets 集合与web.xml配置不一致 defaultAuthenticator 缺乏有效验证 文件上传漏洞关键 : 未过滤的 realFileType 参数 缺乏上传文件类型检查 缺乏路径规范化处理 安全开发建议 : 保持权限校验的一致性 对所有用户输入进行严格验证 实现最小权限原则 定期进行安全审计 参考资源 致远OA wpsAssistServlet任意文件上传漏洞分析 致远OA官方安全公告 OWASP文件上传安全指南