1. 簡介

這份研究論文針對「SOAPwn」漏洞提供了深入的技術分析,這是一個位於 .NET Framework 的 SoapHttpClientProtocol HttpWebClientProtocol 類別中的設計缺陷。該漏洞允許 Threat actor 透過操作 Service URL 來繞過預期的 HTTP-only 通訊,進而導致非 HTTP 的 WebRequest 物件(例如 FileWebRequest )被建立。這種錯誤行為可被利用來達成任意檔案寫入操作,隨之引發嚴重的安全性影響,包括透過上傳 webshell 達成遠端程式碼執行 (Remote Code Execution, RCE)。分析重點在於 GetWebRequest 方法內部的關鍵程式碼路徑,以及涉及 Web Services Description Language (WSDL) 操作的攻擊鏈。

隱藏在 .NET 內的未爆彈:別讓 SOAPwn 漏洞成為駭客入侵的後門 | 資訊安全新聞

1. 簡介

.NET Framework 是企業級應用程式開發中廣泛採用的平台,其內建支援使用基於 SOAP 的 web services。此功能依賴於用戶端代理類別(通常從 WSDL 檔案產生),這些類別繼承自 SoapHttpClientProtocol 。這些代理旨在處理將方法呼叫序列化為 SOAP 訊息,並透過 HTTP 傳輸。然而,基底類別在處理服務端點 URL 時的一個關鍵設計疏失,引入了一個嚴重的漏洞。這個被稱為 SOAPwn 的瑕疵,展示了在類型檢查和物件處理中一個看似微小的問題,如何導致根本性的安全性繞過,允許 Threat actor 將 SOAP 請求主體從 HTTP 網路串流轉向為本機檔案系統的寫入操作 [1]

2. 漏洞技術深入解析

SOAPwn 漏洞的核心存在於 System.Web.Services.Protocols.HttpWebClientProtocol.GetWebRequest(Uri uri) 方法中。此方法負責建立處理實際網路通訊的底層 WebRequest 物件。預期的行為是確保所有的 SOAP 請求都由 HttpWebRequest 處理,這對於 web service 通訊是合適的。然而,該方法的實作未能嚴格強制執行使用 HTTP 或 HTTPS 方案。

利用此漏洞的關鍵在於 .NET Framework 的 WebRequest.Create(uri) 方法是與協定無關的。如果提供的 URI 使用非 HTTP 方案(例如 file:// ), WebRequest.Create 將回傳一個特定協定的處理常式,在此案例中為 FileWebRequest 。隨後在 GetWebRequest 中的邏輯試圖使用 as 運算子將回傳的 WebRequest 轉型為 HttpWebRequest ,這正是失效點 [1] 。關鍵程式碼路徑如下:

  1. protected override WebRequest GetWebRequest(Uri uri)
  2. {
  3. // [1] WebRequest.Create(uri) is called internally by base.GetWebRequest(uri).
  4. // If uri is "file:///C:/path/to/file.aspx", this returns a FileWebRequest.
  5. WebRequest webRequest = base.GetWebRequest(uri);
  6. // [2] Attempt to cast the generic WebRequest to the expected HttpWebRequest.
  7. // If webRequest is a FileWebRequest, httpWebRequest will be null.
  8. HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;
  9. // [3] The code checks if the cast was successful.
  10. if (httpWebRequest != null)
  11. {
  12. // Set various HTTP headers and properties (UserAgent, Proxy, etc.)
  13. httpWebRequest.UserAgent = this.UserAgent;
  14. // ...
  15. if (this.proxy != null)
  16. {
  17. httpWebRequest.Proxy = this.proxy;
  18. }
  19. // ...
  20. }
  21. // [4] CRITICAL FLAW: The original webRequest is returned regardless of the cast result.
  22. // If it was a FileWebRequest, it is returned and used for the SOAP request.
  23. return webRequest;
  24. }

當使用 malicious payload URI(例如 file:///path/to/webshell.aspx )時, httpWebRequest 變數在步驟 [2] 會變為 null 。步驟 [3] 的條件區塊會被跳過,並在步驟 [4] 回傳原始的 FileWebRequest 。由於 SoapHttpClientProtocol 基底類別隨後會嘗試將 SOAP 請求主體寫入到回傳的 WebRequest 串流中, FileWebRequest 將其解釋為對本機檔案系統的檔案寫入操作。此機制有效地將標準的 SOAP 方法呼叫轉換為任意檔案寫入原始碼。

3. 透過 WSDL 操作的攻擊向量

主要的攻擊向量涉及操作服務端點 URL,該 URL 通常定義在用於產生用戶端代理的 WSDL 檔案中。當開發人員使用 ServiceDescriptionImporter 類別從 Threat actor 控制的 WSDL 產生代理時,產生的代理類別將包含惡意 URL。定義服務端點的 WSDL 結構是 <service> 區段內的 <soap:address> 元素:

  1. <service name="MaliciousService">
  2. <port name="MaliciousServiceSoap" binding="tns:MaliciousServiceSoap">
  3. <soap:address location="file:///C:/inetpub/wwwroot/webshell.aspx" />
  4. </port>
  5. </service>

藉由將 location 屬性設定為指向可透過網頁存取的目錄(例如 IIS 或 ASP.NET 根目錄)的 file:// URI,Threat actor 可以確保其完全控制的 SOAP 請求主體被寫入到指定的檔案中。這允許上傳 webshell(例如包含任意 C# 程式碼的 ASPX 檔案),直接導致 RCE。在應用程式動態產生或取用來自外部或不可信來源 WSDL 的情境中,這種技術特別強大。

利用應用程式自身的合法功能(SOAP client)來執行惡意行為的能力,是「Living-off-the-Land」技術的典型案例,這在原理上類似於其他基於 .NET 的惡意軟體如何利用 PowerShell 和 WMI 等合法系統工具來達成無檔案持續性與執行 [2]

4. 攻擊流程圖

下圖說明了當處理惡意 file:// URI 時,受漏洞影響方法內的執行流程,並突出了導致檔案寫入操作的路徑。

graph TD A[Client Proxy
Invokes
SOAP Method] --> B(Set Url Property
to
file:///path/webshell.aspx); B --> C{"Call
base.GetWebRequest(uri)"}; C --> D["WebRequest.Create(file://)
Returns
FileWebRequest"]; D --> E{Attempt Cast:
webRequest
as
HttpWebRequest}; E -- Cast Fails
(FileWebRequest) --> F[httpWebRequest = null]; F --> G{Check if
httpWebRequest != null}; G -- False --> H[Skip
HTTP-Specific
Setup]; H --> I[Return Original
FileWebRequest]; I --> J[SoapHttpClientProtocol
Writes SOAP Body]; J --> K[FileWebRequest
Interprets
Write as
File System Operation]; K --> L(Arbitrary
File Write /
Webshell Upload); L --> M[Remote Code Execution];

5. 緩解措施與結論

SOAPwn 漏洞突顯了一個基本的安全性原則:輸入驗證必須全面,並在儘可能早的時點強制執行。在此案例中,將 URI 方案傳遞給與協定無關的 WebRequest.Create 函式之前未進行驗證是根本原因。雖然此漏洞存在於 .NET Framework 的設計中,但緩解責任主要落在應用程式開發人員身上。

開發人員必須對任何 SoapHttpClientProtocol 執行個體的 Url 設定實施嚴格驗證,確保僅允許 http https 方案。此外,動態取用外部來源 WSDL 的應用程式應將 WSDL 內容視為不可信輸入,並在產生代理之前對 <soap:address> 的 location 屬性進行淨化。對 GetWebRequest 方法的技術分析確認了該漏洞是寬鬆的類型轉型與回傳邏輯的直接後果,允許 non-HTTP request object 通過 SOAP transmission pipeline。

總之,SOAPwn 瑕疵是一個關鍵的提醒,安全性漏洞可能深深植根於看似無害的架構邏輯中。透過分析反組譯後的程式碼並理解物件生命週期,我們可以清楚地看到 HttpWebClientProtocol 類別中缺乏嚴格的協定強制執行,如何啟用了一個強大的攻擊原始碼,將標準的 web service 呼叫轉變為任意檔案系統操作及後續 RCE 的手段。