.NET SOAP/WSDL Client Proxy Abuse
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
TL;DR
SoapHttpClientProtocol,DiscoveryClientProtocoland friends inherit fromHttpWebClientProtocol, whoseGetWebRequest()returns the scheme-agnosticWebRequestinstance produced byWebRequest.Create()without enforcingHttpWebRequest.- If an attacker controls the proxy
Url, the framework silently swaps inFileWebRequest,FtpWebRequestor UNC/SMB handlers, turning “HTTP” proxies into NTLM leak gadgets or arbitrary file writers. - Any feature that imports attacker-supplied WSDL with
ServiceDescriptionImportercompounds 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)://→HttpWebRequestfile:///or\\host\share\→FileWebRequestftp://→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
- Gain control over
SoapHttpClientProtocol.Url(direct setter, config value, database row, etc.). - Point it to a UNC path like
file://attacker.local/sink/payload. - The CLR opens the path via SMB and performs integrated authentication, leaking NTLM challenge/response to the attacker.
- 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://
- Set
Url = "file:///inetpub/wwwroot/poc.aspx"(or any writable path) before the proxy call. - Invoke any SOAP method; the framework writes the entire SOAP envelope to the chosen path, overwriting existing files.
- 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
<script>via plain strings requires additional tricks. - Meaningful payloads need at least one attacker-influenced argument or the ability to modify the method signature (see WSDL abuse).
Runtime often throws Client found response content type of 'application/octet-stream', but expected 'text/xml' after the write—treat this error as an IOC.
Weaponizing WSDL imports
Auto-generated proxies via ServiceDescriptionImporter
Many products expose “custom web service” features that accept a WSDL URL, then:
ServiceDescription.Read()the attacker-controlled WSDL.ServiceDescriptionImportergenerates C# proxy classes extendingSoapHttpClientProtocol.- CodeDOM compiles the proxy and reflection calls the requested method.
The attacker fully controls:
soap:address/soap12:addresslocation→ becomesbase.Url(can setfile://or UNC paths).- Method names, parameter lists, complex types and serializers.
- Namespace URIs that end up as
xmlns:*attributes in every SOAP message.
No scheme validation occurs, so every generated proxy inherits the original design flaw.
Shaping the SOAP envelope for RCE
- Complex type serialization: Define custom structs in the WSDL so that when
XmlSerializerre-emits them, they produce attacker-chosen element names/attributes. For ASPX webshell drops, craft types that serialize to:
and point<script runat="server"> // payload pulling `Request.QueryString["cmd"]` </script>Urltofile:///.../webroot/shell.aspxto 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 <script runat="server"> via complex parameters, and uploaded a webshell that executed arbitrary cmd.exe commands.
Typical attack workflow
- Identify functionality that accepts a WSDL URL or otherwise lets users configure SOAP endpoints (e.g., Barracuda
InvokeRemoteMethod, Ivanti EPM connectors, Umbraco 8 Forms datasources, PowerShellNew-WebServiceProxy). - Host a malicious WSDL whose
soap:addresspoints to a writable path or UNC share and whose schema definitions provide payload-friendly methods/types. - Trigger the import/compilation. The target emits a proxy DLL with attacker-controlled constructor and methods.
- When the application invokes the generated method, the SOAP request is serialized and written to the attacker-specified path, embedding the payload.
- Execute the dropped file (browse to
poc.aspx?cmd=whoami, load the CSHTML, or let PowerShell run the script) or replay captured NTLM material.
Detection & hunting
- Static analysis: Grep for
ServiceDescriptionImporter,SoapHttpClientProtocol,HttpWebClientProtocol, orNew-WebServiceProxy. Trace howUrlor WSDL inputs are sourced—anything user-controlled is a red flag. - Runtime telemetry:
- Instrument proxy creation to log schemes; alert on
file,ftp, or UNC values. - Monitor for the characteristic “Client found response content type of ‘application/octet-stream’” errors after SOAP calls.
- Watch for unexpected
.aspx/.cshtml/.ps1writes under application directories performed by the web service identity.
- Instrument proxy creation to log schemes; alert on
- Network/file signals: SMB connections initiated by web servers to attacker infrastructure, or sudden compilation of temporary proxy DLLs, often precede exploitation.
Mitigations
- Enforce transport validation before invoking any
HttpWebClientProtocol-derived proxy:var uri = new Uri(proxy.Url); if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) throw new InvalidOperationException("SOAP clients must stay on HTTP/S"); - Sanitize imported WSDL: Proxy downloads through a broker that rewrites or rejects
soap:addressentries that are not HTTP/S, drops unknown bindings, and forbids namespace payload tricks. - Disable untrusted WSDL features: Replace “upload a WSDL” conveniences with vetted, server-side templates or allowlists.
- Segregate write locations: Ensure app pools cannot write into executable directories; use separate volumes for data vs. code so that file-write primitives do not become RCE.
- Harden NTLM exposure: Disable outbound SMB where possible; otherwise enforce SMB signing, EPA and other relay mitigations.
References
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
HackTricks

