某思oa代码审计记录
字数 3178
更新时间 2026-03-12 13:01:20

某思OA系统代码审计与漏洞分析教学文档

本文档基于对《某思oa代码审计记录》一文的内容提炼与知识整合,旨在系统性地讲解一次针对某思OA系统的安全审计过程,剖析其中发现的关键漏洞,并总结审计思路与方法。文档将遵循“整体架构分析 -> 关键模块审计 -> 漏洞点详解”的逻辑展开。

第一章:系统安全框架分析与鉴权绕过

审计的第一步是理解系统的安全过滤机制,以评估攻击面。

  1. 统一入口与过滤器(Filter)分析

    • 系统通过CheckFilter*.jsp*.do接口进行统一鉴权。
    • 鉴权逻辑的核心是验证用户会话(Session)中是否存在有效的userId。若未授权(即userId为空),则请求会被拦截。
  2. 鉴权逻辑的细化与潜在绕过的分析

    • CheckFilter中存在一个条件分支,其判断依赖于SystemCommon.getCustomerName()的返回值是否为ceb。但文档指出,在实际配置中该值默认为空,因此此分支通常不生效,应重点关注后续通用鉴权逻辑。
    • 关键鉴权路径:过滤器会从请求URI中提取路径,并进行两项关键检查:
      • 路径黑名单检查:如果请求路径包含/upload并以.jsp结尾,无论是否登录,都会被强制返回登录界面。这是一个针对特定路径的硬性规则。
      • 权限与忽略列表检查
        • managerActionRight参数:该参数在ParameterFilter.class中设置,其值代表当前用户有权访问的路由列表。过滤器会检查请求路径是否在该列表中,不在则无权访问。
        • ignoreList参数:同样在ParameterFilter.class中设置,代表可绕过鉴权的白名单路由。理论上,访问此列表中的路由无需鉴权。
    • 实际验证与矛盾:审计者对公网资产进行测试时发现,即使访问ignoreList中的路由,仍然需要进行鉴权。这表明实际部署的代码逻辑可能与当前分析的代码存在差异,或配置未生效,这在老旧系统中是常见现象。审计启示:代码静态分析需结合动态测试验证。

第二章:高危漏洞点审计与分析

在理清鉴权框架后,审计深入到具体功能模块,发现了两个高危漏洞。

漏洞一:未授权/任意文件上传漏洞

  1. 入口定位

    • 该功能基于Struts框架。首先在相关配置文件(如struts-config.xml)中定位到路由声明,例如action路径为/weixinFileUpload
    • 根据Struts映射,找到该路由对应的处理类与方法weixinFileUpload
  2. 参数处理流程

    • 文件路径参数(selectFilePath:该参数由用户传入,并经过了URL双重解码。这意味着攻击者可以通过双重编码(如将../编码为%252e%252e%252f)来绕过可能的路径遍历过滤。
    • 文件保存路径构造
      • 系统会生成一个随机文件名myRandom。当isEdit参数为1时,myRandom直接使用时间戳;否则为“时间戳+6位随机数”。
      • 保存路径的目录部分由path参数(值限定为workflowcustomform)和selectFilePath拼接而成,但selectFilePath仅取最后一个\之后的部分(substring(selectFilePath.lastIndexOf("\\") + 1))。这里的逻辑需要注意:虽然对完整路径进行了截取,但如果攻击者控制的selectFilePath参数本身不包含\,则其值可能被用于构造路径,结合后续的路径拼接,仍可能存在风险,不过文档此处描述略简,需结合代码上下文。
      • 最终保存路径会拼接上根据isEdit值决定的目录以及当前日期。
  3. 核心安全缺陷:后缀名校验失效

    • 系统在checkStuffix方法中对文件后缀名进行校验,逻辑是:若白名单(allowType)不为空,则使用白名单校验;若白名单为空但黑名单(banType)不为空,则使用黑名单校验;若两者都为空,则跳过校验
    • 审计关键发现:allowTypebanType的值从配置文件upload-type-config.xml中读取。然而,实际配置中这两个值都为空。这直接导致后缀名校验逻辑被完全绕过,攻击者可以上传任意后缀的文件(如.jsp, .jspx等Webshell)。
  4. 漏洞利用链

    • 攻击者可以构造一个multipart/form-data请求,调用weixinFileUpload方法。
    • 通过控制selectFilePath参数(可能利用双重解码)和文件内容,在服务器可访问的目录下写入一个Webshell文件。
    • 由于后缀名校验失效,上传的JSP文件可以被成功执行,导致服务器被完全控制。

漏洞二:服务端请求伪造(SSRF)漏洞

  1. 入口与功能

    • 在另一个Struts路由中,存在一个接收url参数的功能点。
    • 该功能会将用户可控的url参数与一个固定字符串拼接,然后通过printFile方法写入特定的日志文件。文档指出,单纯此点利用受限,可能需要结合其他漏洞(如文件读取、文件包含)来利用这个写入日志的行为。
  2. 典型的SSRF漏洞点

    • 在后续代码中,存在一段典型的SSRF漏洞代码:程序会使用用户传入的url,直接发起HTTP/HTTPS请求,并将目标URL的响应内容读取并返回给客户端。
    • 漏洞危害:攻击者可以利用此漏洞,使OA系统服务器作为跳板,发起对内网或其他外部系统的请求。例如:
      • 扫描探测内网存活主机和端口。
      • 攻击内网中不可直接从外网访问的脆弱服务(如Redis, MySQL等)。
      • 访问云服务器元数据接口(如169.254.169.254),获取敏感凭证。
      • 与文件上传漏洞结合,实现更复杂的攻击链。

第三章:审计总结与通用方法论

  1. 审计路径

    • 入口 -> 过滤器 -> 业务逻辑:这是Web应用代码审计的经典路径。首先定位全局安全控制点(如Filter、AOP),分析其绕过可能,再深入具体业务功能。
    • 框架特性利用:对于Struts、Spring MVC等框架,从配置文件定位路由与类方法的映射关系是快速定位功能点的关键。
  2. 安全机制深度验证

    • “配置即代码”:安全机制的开关和规则往往由配置文件决定。必须审计相关配置(如upload-type-config.xml),确认黑白名单、开关是否实际生效。本例中,校验逻辑因配置为空而形同虚设。
    • 逻辑矛盾验证:当代码逻辑(如ignoreList)与实测行为不符时,需考虑代码版本、环境差异或动态运行时逻辑,不能完全信任静态分析。
  3. 漏洞模式识别

    • 文件上传漏洞:重点审计路径构造(用户输入拼接、路径遍历)、文件名生成(是否可预测、是否用户可控)、内容校验(文件头、内容)、后缀校验(黑白名单机制是否有效、是否可绕过)。
    • SSRF漏洞:重点寻找直接使用用户输入构造请求URL的代码,并检查是否有对协议(如限制file://gopher://)、地址(如限制内网IP)、端口的过滤。
  4. 输入处理的链条追踪

    • 对用户输入的参数(如本例的selectFilePath, url)要进行完整的“数据流”追踪,观察其是否经过解码、拼接、拆分、重组等操作。例如URL双重解码是常见的绕过WAF或简单过滤的手段。

通过本次审计案例可以看出,一个看似完备的系统,可能在全局鉴权、具体业务逻辑校验、安全配置等多个层面存在疏漏,需要审计人员具备系统的视角和细致的代码追踪能力。

相似文章
相似文章
 全屏