Full Report
HttpWebClientProtocol has several variants of it - the main focus in this post is SoapHttpClientProtocol. Since this has HTTP in it, it's completely understandable that it would only support HTTP. In reality, it will handle other file URIs. When calling the creation code for the request, it can return different types. Naturally, the HttpWebRequest type is casted to. If the types don't match, this will fail though. For whatever reason, the proxy code for Microsoft doesn't do the casting check. So, if you can trick the code to use an arbitrarily URL, the response object will also be different. When using the SOAP proxy, it's possible to "send" SOAP requests to a local file. Why would this ever be needed? Who knows! This behavior can be use to perform arbitrary writes but requires control over the file content. This attack can only be used on SOAP XML content and is application specific. When they reported this to Microsoft, they decided not to fix it. This feels like a bug in Microsoft libraries based on the naming convention and reasonable assumptions. They blamed users for the issue and said that SoapHttpClientProtocol should never be user controlled. So, the quirk sat around for a while... Since Microsoft said this wasn't their fault, they started looking for ways to exploit this further. A year later, a colleague of the author decided to look into Barracuda Service Center. While reviewing this code, they found some code that was generating WSDL proxy classes on the fly. While doing this, it's possible to set the soap address to be a file. When the proxy is generated, the application writes SOAP messages to the attacker controlled path. This appeared to be a common pattern in several applications. Since the WSDL code is mainly controlled by the attacker, the generated SOAP HTTP client proxy has a lot of control as well. So, we don't only control the location of the file write but much of the content as well. XML tag names were the main thing that could be controlled. In some cases, the values could be controlled too. For getting RCE, the location and the value both matter. Their first major exploit was creating an ASPX webshell. ServiceDescriptionImporter doesn't have a simple method for controlling the attributes in the tags. Luckily enough, complex types can be used to smuggle in XML attributes in various paths. With this, you have enough control over a SOAP body through WSDL to create a functional ASPX webshell. In cases where none of the input arguments are controllable, there is one other to exploit: namespaces. By defining a namespace in the WSDL as a valid URL, the query string gets smuggled in as special characters. When the SOAP method is executed, the request body will include the namespace information. This can be used to create CSHTML webshells and run malicious Powershell scripts. This feels like a template injection more than anything else into the valid C# proxy code. Microsoft still rejected the issue, even after finding several applications that were vulnerable. They claim this is still the developers fault. At least some documentation was added for this. This was an absolutely beautiful class of vulnerabilities. I appreciate the concise description about the issue, what is required to exploit this and the impact of it. Great post!
Analysis Summary
# Vulnerability: SOAPwn - .NET SOAP Client Proxy File Write / RCE
## CVE Details
- **CVE ID:**
- **CVE-2025-34392** (Barracuda Service Center RMM)
- **CVE-2025-13659** (Ivanti Endpoint Manager)
- **CVSS Score:** Not explicitly listed, but the impact is verified as **High/Critical** (Unauthenticated RCE).
- **CWE:** CWE-91: XML Injection; CWE-706: Use of Incorrectly-Resolved Name or Reference.
## Affected Systems
- **Products:**
- .NET Framework (Core Classes: `SoapHttpClientProtocol`, `DiscoveryClientProtocol`, `HttpSimpleClientProtocol`)
- Barracuda Service Center RMM
- Ivanti Endpoint Manager (EPM)
- Umbraco 8 CMS
- Microsoft PowerShell / SQL Server Integration Services (SSIS)
- **Versions:** Specific to .NET Framework 4.8.1 and earlier; vendor-specific versions as noted below.
- **Configurations:** Applications that use `ServiceDescriptionImporter` to generate proxy classes from user-supplied WSDL files or allow user control over the `Url` property of a SOAP client.
## Vulnerability Description
The flaw exists in how the .NET `HttpWebClientProtocol` class (and its children like `SoapHttpClientProtocol`) handles URIs. Despite the "HTTP" naming, the `GetWebRequest` method does not restrict protocol schemes. If an attacker controls the `Url` property, they can supply a `file://` URI.
When the application attempts to "send" a SOAP request to a local file path, the protocol handler fails to perform a type-check cast to `HttpWebRequest`. Because Microsoft's proxy code lacks this casting check, the response object is handled incorrectly, allowing the application to write the SOAP request body directly to a local file. By manipulating WSDL namespaces and complex types, attackers can smuggle arbitrary content (like ASPX tags or PowerShell scripts) into the SOAP body, resulting in a primitive for arbitrary file write.
## Exploitation
- **Status:** PoC Available / Disclosed at Black Hat Europe 2025. Exploited against enterprise appliances.
- **Complexity:** Medium (Requires knowledge of WSDL structure to smuggle payloads).
- **Attack Vector:** Network (often via WSDL ingestion or SSRF-like URL control).
## Impact
- **Confidentiality:** High (Potential for NTLM relaying or data exfiltration).
- **Integrity:** High (Arbitrary file write allows for web shell creation).
- **Availability:** High (RCE allows for complete system takeover).
## Remediation
### Patches
- **Barracuda:** Fixed in Service Center RMM hotfix **2025.1.1**.
- **Ivanti:** Patched in recent updates for Endpoint Manager.
- **Microsoft:** Microsoft has classified this as "Expected Behavior" / Developer Error and has **not** issued a framework-level patch, opting instead for documentation updates.
### Workarounds
- Ensure that the `Url` property of any `SoapHttpClientProtocol` instance is never derived from user-controllable input.
- Sanitize WSDL files before passing them to `ServiceDescriptionImporter`.
- Restrict application permissions to prevent writing to web-accessible directories or sensitive system paths.
## Detection
- **Indicators of Compromise:**
- Unexpected creation of `.aspx`, `.cshtml`, or `.ps1` files in application directories.
- SOAP requests containing XML namespaces that look like local file paths or include escaped characters (e.g., `?`, `&`, or encoded shell commands).
- **Detection Methods:**
- Static Analysis (SAST): Scan code for `ServiceDescriptionImporter` or `SoapHttpClientProtocol.Url` assignments linked to external inputs.
- Monitor for processes where the web server (IIS) initiates unexpected file writes to its own web roots.
## References
- WatchTowr Labs Blog: hxxps[://]labs[.]watchtowr[.]com/soapwn-pwning-net-framework-applications-through-http-client-proxies-and-wsdl/
- Researcher Whitepaper: hxxps[://]watchtowr[.]com/wp-content/uploads/SOAPwnwatchtowr_soappwn-research-whitepaper_10-12-2025[.]pdf
- Microsoft Documentation: hxxps[://]learn[.]microsoft[.]com/en-us/dotnet/api/system.web.services.protocols.soaphttpclientprotocol