SOAP/JAX-WS ThreadLocal Authentication Bypass

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

  • Certaines chaînes de middleware stockent le Subject/Principal authentifié dans un ThreadLocal statique et ne le rafraîchissent que lorsqu’un en-tête SOAP propriétaire arrive.
  • Parce que WebLogic/JBoss/GlassFish recyclent leurs worker threads, la suppression de cet en-tête entraîne la réutilisation silencieuse du dernier Subject privilégié traité par le thread.
  • Bombardez l’endpoint vulnérable avec des corps SOAP bien formés mais sans en-tête jusqu’à ce qu’un thread réutilisé vous accorde le contexte administrateur volé.
  • 2025 HID ActivID/IASP (HID-PSA-2025-002) est un cas réel : le handler JAX-WS met en cache un SubjectHolder ThreadLocal, permettant aux appels SOAP non authentifiés d’hériter de l’identité définie par des requêtes console/SSP précédentes.

Cause racine

Des handlers similaires au suivant n’écrasent l’identité thread-local que lorsque l’en-tête personnalisé est présent, donc le contexte de la requête précédente survit :

public boolean handleMessage(SOAPMessageContext ctx) {
if (!outbound) {
SOAPHeader hdr = ctx.getMessage().getSOAPPart().getEnvelope().getHeader();
SOAPHeaderElement e = findHeader(hdr, subjectName);
if (e != null) {
SubjectHolder.setSubject(unmarshal(e));
}
}
return true;
}

Recon

  1. Énumérez les règles de reverse proxy / de routage pour localiser des arbres SOAP cachés qui peuvent bloquer ?wsdl tout en acceptant des POSTs (cartographiez-les parallèlement au flux dans 80,443 - Pentesting Web Methodology).
  2. Décompressez les artefacts EAR/WAR/EJB (unzip *.ear) et inspectez application.xml, web.xml, les annotations @WebService et handler chains (par ex., LoginHandlerChain.xml) pour découvrir la classe handler, le QName de l’en-tête SOAP, et les noms des EJB sous-jacents.
  3. Si les métadonnées sont absentes, brute-force les chemins probables ServiceName?wsdl ou détendez temporairement les proxies du lab, puis importez tout WSDL récupéré dans des outils tels que Burp Suite Wsdler pour générer des enveloppes de base.
  4. Examinez les sources des handlers à la recherche de gardiens ThreadLocal (par ex., SubjectHolder.setSubject()) qui ne sont jamais nettoyés lorsque l’en-tête d’authentification est absent ou malformé.

Exploitation

  1. Envoyez une requête valide avec l’en-tête propriétaire pour connaître les codes de réponse normaux et toute erreur utilisée pour les tokens invalides.
  2. Renvoyez le même SOAP body tout en omettant l’en-tête. Gardez le XML bien formé et respectez les namespaces requis afin que le handler se termine proprement.
  3. Bouclez la requête ; lorsqu’elle atterrit sur un thread ayant précédemment exécuté une action privilégiée, le Subject réutilisé débloque des opérations protégées telles que les gestionnaires d’utilisateurs ou d’identifiants.
POST /ac-iasp-backend-jaxws/UserManager HTTP/1.1
Host: target
Content-Type: text/xml;charset=UTF-8

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:jax="http://jaxws.user.frontend.iasp.service.actividentity.com">
<soapenv:Header/>
<soapenv:Body>
<jax:findUserIds>
<arg0></arg0>
<arg1>spl*</arg1>
</jax:findUserIds>
</soapenv:Body>
</soapenv:Envelope>

2025 HID ActivID/IASP étude de cas (HID-PSA-2025-002)

  • Synacktiv a montré que le LoginHandler JAX-WS dans ActivID 8.6–8.7 assigne SubjectHolder.subject lorsque l’en-tête SOAP mySubjectHeader est présent ou lorsque le trafic console/SSP s’authentifie, mais ne le supprime jamais quand l’en-tête est absent.
  • Tout appel SOAP ultérieur sans l’en-tête sur le même worker thread hérite de ce Subject en cache, permettant la création non authentifiée d’utilisateurs administrateurs ou l’importation d’identifiants via des endpoints tels que UserManager ou CredentialManager.
  • Schéma d’exploitation fiable observé :
  1. Déclencher un contexte authentifié sur de nombreux threads (par ex., spammer /ssp ou se connecter à /aiconsole en tant qu’admin dans un autre onglet du navigateur).
  2. Inonder avec des corps SOAP sans en-tête /ac-iasp-backend-jaxws/UserManager ou d’autres endpoints JAX-WS soutenus par des EJB avec un fort parallélisme ; chaque requête qui réutilise un thread “infected” s’exécute avec un Subject élevé.
  3. Répéter jusqu’à obtenir des réponses privilégiées ; réutiliser les connexions Keep-Alive et de grands pools de workers pour maximiser la probabilité de réutilisation de threads.
  • Points clés du handler et du flux de traitement :
  • LoginHandlerChain.xmlLoginHandler.handleMessage() désérialise mySubjectHeader et stocke le Subject dans SubjectHolder (un ThreadLocal static).
  • ProcessManager.triggerProcess() injecte ensuite SubjectHolder.getSubject() dans les processus métier, donc les en‑têtes manquants laissent les identités obsolètes intactes.
  • Le PoC sur le terrain issu de l’avis utilise un abus SOAP en deux étapes : d’abord getUsers pour leak des informations, puis createUser + importCredential pour implanter un administrateur malveillant lorsqu’un thread privilégié est utilisé.

Validation du bug

  • Attacher JDWP (-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n) ou des hooks de débogage similaires pour surveiller le contenu du ThreadLocal avant et après chaque appel, confirmant qu’une requête non authentifiée a hérité d’un Subject administrateur antérieur.
  • Sur des appliances en production, vous pouvez aussi instrumenter avec JFR ou BTrace pour dumper SubjectHolder.getSubject() par requête, vérifiant la réutilisation sans en‑tête.

References

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