CVE 漏洞利用與攻擊流程報告

復現兩個不同信任邊界的漏洞,將 PoC、機制與可交接的證據整理成課程報告。

CVE Research PHP-CGI React Server Components Exploit Analysis

專題定位:把「跑通 PoC」拆成可審查的證據

這是資訊安全課程攻防平台(CDX)的受控實驗。我擔任組長,負責挑選 CVE、分配研究工作、查閱漏洞報告與公開 PoC,並把兩條攻擊流程整理成流程視覺化。我的主要實作是 CVE-2025-55182:追蹤根因與觸發條件、撰寫復現腳本,以及完成大部分簡報與插圖;在 CVE-2024-4577 則協助補充其他攻擊面與 Windows 字元轉換機制。

這份報告的判斷單位不是「某個 payload 成功了」,而是:不受信任的輸入在哪個邊界被交給下一個解讀器、哪個假設失效、實驗留下了什麼可核對的證據,以及修補後應該觀察到什麼變化。兩個 CVE 沒有共同的利用鏈,分別代表命令列參數解析與伺服器端資料還原的問題。

案例 不受信任輸入進入的解讀器 信任邊界 受影響範圍的判斷
CVE-2024-4577 Windows code page 與 PHP-CGI 命令列解析 HTTP 請求 → CGI process arguments Windows Apache 以 CGI 呼叫 php-cgi.exe,且部署使用受影響的 code page/PHP 版本
CVE-2025-55182 React Flight multipart payload 的 chunk 還原 HTTP 請求 → RSC Server Function handler 使用 RSC/Server Function 且載入受影響 react-server-dom-* 套件與版本的伺服器

CVE-2024-4577 與 CVE-2025-55182 的分流流程:請求分別進入 Windows PHP-CGI 參數解析和 React RSC chunk 還原邊界

CVE-2024-4577:Windows PHP-CGI 的參數注入

信任邊界與根因

本案的邊界不是 PHP 應用程式裡的某一個表單,而是 Windows Apache 將 HTTP 請求交給 php-cgi.exe 時,請求內容如何成為 CGI process 的參數。部分 Windows code page 會在 Unicode-to-ANSI 的 Best-Fit conversion 中,把原本不是 ASCII hyphen 的輸入轉成具有選項意義的 ASCII -。PHP-CGI 後續依命令列規則解析它,於是原本應被視為資料的內容可能變成 interpreter option。

根因是字元轉換與參數解析之間的假設不一致:Web 層認為自己傳遞的是資料,Windows 的相容性轉換卻改變了字元語義,而 PHP-CGI 沒有在這個邊界阻止輸入進入 option parser。這不是「所有 PHP 都能利用」的結論;必須同時核對作業系統、code page、Web server 的 CGI mapping、PHP 分支與修補狀態。

高層次利用邏輯

從 HTTP request 經 Windows Apache CGI invocation、Best-Fit conversion 與 php-cgi option parsing 的高層次解析鏈如圖所示。

CVE-2024-4577 從 HTTP 請求到 PHP-CGI 參數解析的高層次信任邊界流程

攻擊者的控制點是能到達 CGI invocation 的請求輸入;關鍵轉折是轉換後的字元被 PHP-CGI 當成 option-significant hyphen。後續影響取決於可用的 PHP-CGI 參數與部署權限,因此這裡只說明解析鏈,不放可直接執行的 option 或 payload。

受影響配置與 CDX 證據

我們在 CDX 平台將 Windows Apache、PHP-CGI、code page 與 PHP 修補版本當成實驗條件,而不是把「Windows + PHP」當作充分條件。復現紀錄分開保存原始請求、轉換後的字元/參數、php-cgi.exe 的解析結果與 HTTP 回應;流程圖用這幾個觀察點標出輸入真正跨過的邊界。對照不同 code page 或已修補版本時,解析結果不應再把轉換後的資料當成未預期的 option。這項證據支持「字元轉換造成參數語義改變」的根因,但不宣稱每一個 PHP-CGI 配置都有相同結果。

偵測、修補與限制

  • 先盤點 Windows Apache 的 CGI mapping、PHP-CGI 版本與系統 code page;再依 PHP 與發行者的安全公告升級到修補版本。能改用不需要直接把請求映射到 PHP-CGI 的 SAPI 時,也應納入架構修正。
  • 在 Apache/WAF/process telemetry 中保留原始請求與實際 process command line,對非預期的 option-like 字元、PHP-CGI 啟動參數變化,以及 Web process 衍生異常子程序建立關聯。只看應用程式回應,可能看不到轉換發生的那一層。
  • 以最小權限執行 Web process、限制不必要的 CGI 路由,並把 code page 與部署設定納入版本化檢查。WAF 規則可以是暫時的觀測或緩解,不應替代 PHP 修補。

CVE-2025-55182:React Server Components 的資料還原邊界

受影響配置與信任邊界

本案的輸入是送往 React Server Function/RSC handler 的 Flight multipart request。React 伺服器端會把 chunks 還原成模型與函式呼叫;因此客戶端可提交的資料,最後會進入伺服器端的 decoder,而不只是被渲染成前端畫面。React 官方公告列出的受影響套件是 react-server-dom-webpack、react-server-dom-parcel 與 react-server-dom-turbopack 的 19.0、19.1.0、19.1.1、19.2.0;修補版本包含 19.0.1、19.1.2、19.2.1。

受影響條件還要看框架/bundler 是否支援 RSC,以及應用程式是否真的把這些套件接到伺服器端端點。瀏覽器端 React 或沒有 RSC server 的應用程式不能直接套用本案結論;同樣地,也不應把它寫成「所有 React app 都受影響」。

根因與高層次利用邏輯

在我負責追蹤的 decoder 路徑中,reviveModel、parseModelString 與 getOutlinedModel 會處理互相參照的 Flight chunks。問題在於解析屬性路徑時缺少可靠的 own-property validation:不受信任的 key 可以沿著物件繼承鏈找到 constructor 等 inherited property,卻被當成模型本身提供的安全欄位。這讓本來應是資料的 reference 有機會變成可呼叫的函式/物件,跨入 Server Function 的執行語境。

從不受信任的 Flight multipart request 到 Server Function handler 伺服器端執行風險的高層次流程如圖所示。

CVE-2025-55182 從 Flight 請求到 Server Function 執行風險的高層次信任邊界流程

這條鏈與 CVE-2024-4577 的 Windows 字元轉換完全無關;它不依賴 PHP、Apache 或命令列 option parser。React 官方公告將其描述為可由未驗證請求觸發的伺服器端遠端程式碼執行,但本頁不提供可執行的 exploit payload。

我的復現與證據邊界

我負責根因、trigger 與 reproduction script。在 CDX 的受控環境中,腳本以 multipart chunk reference 作為輸入,記錄 decoder 從 reference 還原到伺服器端 handler 的路徑、相關函式與版本條件;簡報中的流程插圖則把 parser 邊界和最後的 server-side execution context 分開。這些 trace/回應是我們對觸發路徑的實驗證據;CVSS 10.0 與未驗證 RCE 的影響分級則引用 React 官方公告,不把課堂環境的觀察誇大成任意生產環境都能利用。

偵測、修補與限制

  • 盤點 lockfile、SBOM、framework/bundler plugin 與實際 RSC route,將 react-server-dom-* 的版本和官方公告逐一比對;升級 React RSC 套件及相依框架/bundler 到修補版本。React 官方明確建議立即更新,hosting provider 的暫時緩解不能代替升級。
  • 在 RSC/Server Function endpoint 監控異常 multipart 請求、非預期的 chunk reference/property path、decoder 例外,以及伺服器程序突然衍生子程序或發生異常網路連線。記錄足夠的 request ID、套件版本與 handler 事件,讓 parser trace 能回到一次請求。
  • 在完成升級前,若產品允許,可限制未驗證的 Server Function/RSC endpoint 暴露面並降低服務帳號權限;這是縮小 blast radius 的暫時措施,不是對漏洞根因的修補。

所學與反思

這次專題讓我把漏洞分析從「找到能跑的 PoC」改成可交接的 source-to-sink tracing:先畫出信任邊界,再把原始輸入、每一層解碼/轉換、版本與部署條件分欄記錄,最後才描述可能影響。我也學到要把「官方公告的影響判定」「自己在 lab 觀察到的結果」和「尚未驗證的推論」分開寫,尤其是 RSC 案例不能用「React app」這種過寬的範圍代替受影響套件與端點。

作為組長,我負責讓兩個不同漏洞仍能用同一套證據格式比較;作為 CVE-2025-55182 的主要實作者,我負責從 getOutlinedModel 等 decoder 函式追到觸發條件、維護復現腳本,並把結果轉成大部分簡報和插圖。對 CVE-2024-4577,我補上額外攻擊面與 Windows character conversion 的分析,讓組員不只看到 PHP-CGI 的結果,也能說明為什麼 code page 會改變參數語義。

完整課程整理見研究簡報。判斷 CVE-2024-4577 的部署範圍可參考 CVE.org 記錄;React 套件、版本與修補範圍以 React 官方公告 為準。