纯真's Blog
纯真's Blog

目录

IDA Pro MCP 部署 & 分析飞牛OS漏洞

最近看到 飞牛NAS OS 被曝存在路径穿越漏洞,结合当下 AI MCP Agent 热度爆火,于是就想记录一下使用MCP来逆向分析溯源的能力。

工具名称版本
系统Windows 10 LTSC 2021 x6421h2
逆向分析工具IDA Pro8.3
MCP AgentIDA Pro MCP2.0.0
AI IDECursor2.4.27
Python版本管理工具uv0.9.28

https://down.52pojie.cn/Tools/Disassemblers/IDA_Pro_v8.3_Portable.zip

下载后将其解压到任意非中文目录

然后运行 IDA_Pro_8.3_绿化工具.exe

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

https://cursor.com/cn/download

安装过程略过。

git clone https://github.com/mrexodia/ida-pro-mcp.git
cd ida-pro-mcp
set UV_DEFAULT_INDEX=https://mirrors.cernet.edu.cn/pypi/web/simple
set UV_PYTHON_INSTALL_MIRROR=https://mirror.nju.edu.cn/github-release/astral-sh/python-build-standalone/
uv sync
uv run ida-pro-mcp --install

运行这条命令会自动将IDA Pro MCP插件复制到 C:\Users\<你的用户名>\AppData\Roaming\Hex-Rays\IDA Pro\plugins 目录当中,同时也会自动检测系统中已安装的AI IDE并自动将MCP json配置文件复制到对应的AI IDE配置文件夹当中。

如果上面的命令没有成功复制MCP json配置文件到你的AI IDE配置文件夹,你也可以手动运行下面的命令生成MCP json然后手动复制粘贴到你的AI IDE当中。

uv run ida-pro-mcp --config

如果上一步的命令已经成功的将MCP json文件复制到对应的目录下则不需要进行这一步操作,否则请按照以下的步骤进行:

首先进入到 ida-pro-mcp 的源代码路径

cd ida-pro-mcp

然后运行:

uv run ida-pro-mcp --config

复制 [STDIO MCP CONFIGURATION] 下面的内容 我这里的json内容是

{
  "mcpServers": {
    "ida-pro-mcp": {
      "command": "C:\\Users\\droidkali\\Desktop\\ida-pro-mcp\\.venv\\Scripts\\python.exe",
      "args": [
        "C:\\Users\\droidkali\\Desktop\\ida-pro-mcp\\src\\ida_pro_mcp\\server.py",
        "--ida-rpc",
        "http://127.0.0.1:13337"
      ]
    }
  }
}

具体以你自己的实际情况为准! 接着我们打开 Cursor 点击右上角的设置图标 找到 Tools & MCP 在右边 Installed MCP Servers 下点击 Add Custom MCP 接着将刚才复制的 MCP json内容粘贴进去并保存 这样我们就完成了 Cursor 的设置.

首先我们按照 飞牛OS任意文件/目录读取漏洞复现,并学习尝试深入系统文件分析信息处理流程 这篇文章作者的思路, 从带有漏洞的飞牛OS里提取相对应的二进制程序

具体路径为 /usr/trim/bin/trim_app_center

我这里提取的飞牛OS系统版本为 v1.0.0

trim_app_center 文件的校验码为

SHA256:

79dab1f0bdcf047c3d4be6115076c527e3f96888012eb6978f0e776786c17ce0 trim_app_center

我们打开 IDA Pro 来加载这个程序 等待 IDA Pro 加载完成, 接着我们点击左上角的 Edit –> Plugins –> MCP Ctrl+Alt+M 等待左下角出现以下输出说明 MCP 服务已经成功运行了

接着我们打开 CursorCtrl + Shift + L 打开对话窗口,然后输入以下提示词

你是一位出色的网络安全专家,现在交给你一项逆向分析任务
背景是这样的,最近飞牛NAS OS被爆出一个路径穿越的漏洞,PoC为: /app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../ 
攻击者可以访问受害者的飞牛NAS系统里的任意文件
我看到漏洞PoC里有app-center的字样,就把带有漏洞的系统相关文件下载了下来现在正在使用IDA Pro加载
你现在已经连接到了IDA Pro的MCP当中
请你调用该MCP帮助我逆向分析漏洞的成因并把分析过程漏洞成因以及修复建议详细的总结下来保存到markdown文档当中.
现在请开始分析

等待 Cursor 自动连接IDA Pro MCP 并进行分析 以下是 Cursor 逆向分析的总结报告:


飞牛 NAS OS app-center-static 路径穿越漏洞逆向分析报告

项目说明
漏洞类型路径穿越 (Path Traversal)
受影响组件飞牛 NAS OS - app-center 静态资源服务
PoC 路径/app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../
危害攻击者可读取受害 NAS 系统上的任意文件
分析环境IDA Pro + user-ida-pro-mcp,Go 二进制逆向
  • URL 解码%7B0%7D{0},即路径中含占位符 {0}
  • 攻击点:查询参数 size=../../../../ 被拼入最终文件路径,导致跳出应用目录,访问任意路径。
  • 路由特征/app-center-static/serviceicon/<appname>/<filename>/,并带有查询参数 size

通过 IDA Pro MCP 在二进制中搜索与漏洞相关的字符串,得到如下地址:

字符串地址说明
app-center0x1592454静态资源路由前缀
serviceicon0x1581a45服务图标子路径
size0x21162ae查询参数名(攻击入口)
../0x2119801路径穿越序列
..\0x2170aecWindows 风格穿越序列

结合函数名可知,处理该路由的控制器为 appstore (app-center) 静态资源模块

在 IDA 中列出与 staticserviceapp 相关的函数,定位到:

函数名地址作用
appstore_core_web_controller._ptr_StaticController.GetStatic0x11542e0漏洞核心:处理 /app-center-static 的静态资源请求
appstore_core_web_controller._ptr_StaticController.GetTmpStatic0x1154c20临时静态资源
appstore_core_web_controller._ptr_StaticController.GetSidebarStatic0x11550a0侧边栏静态资源
appstore_core_util._ptr_StaticUtil.CreateSidebarIconPath0x981200侧边栏图标路径构造
github.com_gin_gonic_gin._ptr_RouterGroup.staticFileHandler0x11451c0Gin 静态文件处理
path_filepath.join0x4f0e80路径拼接
net_http.ServeFile0x6df020最终按路径提供文件

漏洞分析集中在 GetStatic

GetStatic (0x11542e0) 进行反编译后,可还原出如下逻辑(与路径穿越直接相关的部分):

  1. 从 Gin Context 解析参数

    • Route Params:按 Key 长度区分
      • 长度 7 → 对应 appname(应用名)
      • 长度 8 → 对应 filename(文件名/路径片段)
      • 长度 4 → 对应 type(资源类型)
    • Query:通过 net_url__ptr_URL_Query 取 URL 查询,再通过 runtime_mapaccess1_faststr 按 key 取 size 的值。
  2. 按 type 分支

    • 根据 type 与常量字符串比较,进入不同分支(如 icon、poster、wizard、license、serviceicon 等)。
    • 当 type 为 “serviceicon”(长度 11)时,进入存在漏洞的分支。
  3. serviceicon 分支中的路径构造(漏洞点)

    • 使用 appstore_core_util_Replace 将模板中的 ${appname} 替换为路由中的 appname,得到基础路径(形式类似 /var/apps/${appname}/...,具体模板在反编译中为多字符串混合,需结合字符串表确认)。
    • 使用 path_filepath_Join 将「基础路径」与「filename」拼接,得到中间路径(含占位符 {0},用于后续填入图标尺寸)。
    • 使用 strings_Replace 将路径中的占位符 {0} 替换为 URL 查询参数 size 的原始值,得到最终路径。
    • size 仅做了简单长度/内容判断(如长度 3 且为 “256”/“128” 时调用 Faccessat),未对 size 做路径穿越过滤或白名单校验
    • 最后调用 net_http_ServeFile,将上述最终路径作为文件路径,向客户端返回文件内容。

因此,当请求中 size=../../../../ 时:

  • 占位符 {0} 被替换为 ../../../../
  • 最终路径变为「原基础路径 + 路径穿越序列」,从而跳出应用目录;
  • ServeFile 根据该路径读取并返回任意可读文件,形成路径穿越读文件。
请求: GET /app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../

 GetStatic 解析:
   - Params: appname, filename ( {0}), type = "serviceicon"
   - Query: size = "../../../../"

 路径构造:
   base = Replace("/var/apps/${appname}/...", appname)
   path1 = path_filepath_Join(base, filename)   // 路径中仍含 {0}
   path2 = strings_Replace(path1, "{0}", size)  //  {0} 换为 "../../../../"  漏洞

 net_http_ServeFile(response, request, path2)
    访问 path2 对应路径,返回任意文件内容
graph TD
   A["请求: GET /app-center-static/serviceicon/myapp/%7B0%7D/?size=../../../../"] --> B["GetStatic 解析"]
   
   B --> C1["Params:"]
   C1 --> C1a["appname: myapp"]
   C1 --> C1b["filename: {0}"]
   C1 --> C1c["type: serviceicon"]
   
   B --> C2["Query:"]
   C2 --> C2a["size: ../../../../"]
   
   C1b --> D["路径构造"]
   C2a -.-> D
   
   D --> D1["base = Replace('/var/apps/${appname}/...', appname)"]
   D1 --> D2["path1 = path/filepath.Join(base, filename)"]
   D2 --> D3["path2 = strings.Replace(path1, '{0}', size)"]
   
   D3 --> E["net/http.ServeFile(response, request, path2)"]
   E --> F["访问 path2 对应路径"]
   F --> G["返回任意文件内容"]
   
   style A fill:#4a90e2,color:#fff,stroke:#333,stroke-width:2px
   style B fill:#7ed321,color:#fff
   style C1 fill:#f5a623,color:#fff
   style C2 fill:#f5a623,color:#fff
   style D fill:#bd10e0,color:#fff
   style D3 fill:#d0021b,color:#fff,stroke:#900,stroke-width:3px
   style E fill:#9013fe,color:#fff
   style G fill:#d0021b,color:#fff,stroke:#900,stroke-width:3px
   
   linkStyle 4 stroke:#d0021b,stroke-width:2px,stroke-dasharray: 5 5


维度说明
直接原因将 URL 查询参数 size 未经校验地替换到文件路径的占位符 {0} 中,并交给 ServeFile 使用。
设计问题size 本意应为图标尺寸(如 “128”/“256”),却直接参与路径拼接,且未做白名单或规范化。
缺失防护未对 size 做:白名单、..//..\ 过滤、或基于 filepath.Clean + 根路径校验的规范化与边界检查。
利用条件攻击者只需构造合法路由(如 serviceicon + appname + 含 {0} 的 filename),并在查询中传入 size=../../../../ 等序列即可。

  • 做法:仅允许 size 为预定集合(如 "128", "256" 等合法图标尺寸);否则不替换 {0} 或直接返回 400。
  • 示例逻辑(伪代码):
    • size 不在 map[string]bool{"128":true, "256":true} 等白名单中,则:
      • 不使用 size 参与路径拼接,或
      • 返回 400 Bad Request,并记录日志。
  • 优点:改动小、易审计、能彻底杜绝将 size 用作路径穿越。
  • 做法
    1. 使用 filepath.Clean 对「拼接并替换后的路径」做规范化;
    2. 使用 filepath.Abs 得到绝对路径;
    3. 使用 filepath.Rel(baseDir, resolvedPath)strings.HasPrefix 判断解析后的路径是否仍在 baseDir 之下;
    4. 若包含 .. 或不在 baseDir 内,则拒绝请求并返回 403。
  • 注意:在 Go 中应使用 filepath.Rel 检查“结果路径是否仍在根目录内”,避免符号链接等导致的绕过。
  • 所有参与文件路径拼接的输入(Params、Query、Header)均应:
    • 要么白名单校验(如 size 仅允许数字字符串且限定集合);
    • 要么在拼接后做规范化 + 根路径校验,再交给 ServeFile
  • 避免将用户可控字符串直接替换到路径模板中;若必须替换,只允许白名单内的值。
  • 对静态资源接口做访问控制与审计日志,便于发现异常访问。

  • 漏洞函数appstore_core_web_controller._ptr_StaticController.GetStatic @ 0x11542e0
  • 关键调用链
    GetStaticappstore_core_util_Replacepath_filepath_Joinstrings_Replace(..., size)net_http_ServeFile
  • 二进制特征:Go 编译,包含 git.teiron_inc.cnappstore_coregithub.com/gin-gonic/gin 等包路径,与飞牛 NAS app-center 静态服务一致。

报告基于 IDA Pro 与 user-ida-pro-mcp 对飞牛 NAS app-center 相关二进制的逆向分析整理。


国产飞牛系统fnOS疑似出现重大安全漏洞 大量用户数据遭到公开访问

飞牛OS任意文件/目录读取漏洞复现,并学习尝试深入系统文件分析信息处理流程

IDA Pro MCP

相关内容