SOAP/JAX-WS ThreadLocal Authentication Bypass

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Kurzfassung

  • Einige Middleware-Ketten speichern das authentifizierte Subject/Principal in einem statischen ThreadLocal und aktualisieren es nur, wenn ein proprietärer SOAP-Header eintrifft.
  • Da WebLogic/JBoss/GlassFish Worker-Threads recyceln, führt das Weglassen dieses Headers dazu, dass das zuletzt vom Thread verarbeitete privilegierte Subject stillschweigend wiederverwendet wird.
  • Führe wiederholt header-losen, aber wohlgeformten SOAP-Requests an das verwundbare endpoint aus, bis ein wiederverwendeter Thread dir den gestohlenen Administrator-Kontext gewährt.
  • 2025 HID ActivID/IASP (HID-PSA-2025-002) ist ein reales Beispiel: Ein JAX-WS Handler speichert ein SubjectHolder ThreadLocal, wodurch nicht-authentifizierte SOAP-Aufrufe die Identität übernehmen, die durch vorherige console/SSP-Anfragen gesetzt wurde.

Ursache

Handler wie der folgende überschreiben die ThreadLocal-Identität nur, wenn der eigene Header vorhanden ist, sodass der Kontext der vorherigen Anfrage erhalten bleibt:

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. Ermittle die reverse-proxy-/Routing-Regeln, um versteckte SOAP-Bäume zu lokalisieren, die ?wsdl blockieren, aber POSTs akzeptieren (mappe sie entlang des Flows in 80,443 - Pentesting Web Methodology).
  2. Entpacke die EAR/WAR/EJB-Artefakte (unzip *.ear) und untersuche application.xml, web.xml, @WebService-Annotationen und Handler-Chains (z. B. LoginHandlerChain.xml), um die Handler-Klasse, den SOAP-Header-QName und die zugrundeliegenden EJB-Namen aufzudecken.
  3. Falls Metadaten fehlen, brute-force wahrscheinliche ServiceName?wsdl-Pfade oder lockere temporär Lab-Proxies, importiere dann jegliche wiedergewonnene WSDL in Tools wie Burp Suite Wsdler, um Basis-Envelopes zu generieren.
  4. Überprüfe die Handler-Quellen auf ThreadLocal-Keeper (z. B. SubjectHolder.setSubject()), die nicht gelöscht werden, wenn der Authentifizierungsheader fehlt oder fehlerhaft ist.

Exploitation

  1. Sende eine gültige Anfrage mit dem proprietären Header, um die normalen Response-Codes und etwaige Fehler für ungültige Tokens zu ermitteln.
  2. Sende denselben SOAP-Body erneut, während du den Header weglässt. Halte das XML wohlgeformt und beachte die erforderlichen Namespaces, damit der Handler sauber beendet.
  3. Schleife die Anfrage; trifft sie auf einen Thread, der zuvor eine privilegierte Aktion ausgeführt hat, gibt das wiederverwendete Subject Zugriff auf geschützte Operationen wie Benutzer- oder Credential-Manager frei.
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 Fallstudie (HID-PSA-2025-002)

  • Synacktiv zeigte, dass der JAX-WS LoginHandler in ActivID 8.6–8.7 SubjectHolder.subject setzt, wenn ein mySubjectHeader SOAP-Header vorhanden ist oder wenn Konsolen-/SSP-Verkehr authentifiziert, aber diesen nie löscht, wenn der Header fehlt.
  • Jeder nachfolgende SOAP-Aufruf ohne Header im selben Worker-Thread erbt dieses zwischengespeicherte Subject, was die nicht authentifizierte Erstellung von Administrator-Benutzern oder den Import von Credentials über Endpunkte wie UserManager oder CredentialManager ermöglicht.
  • Beobachtetes, zuverlässiges Exploit-Muster:
  1. Erzeuge in vielen Threads einen authentifizierten Kontext (z. B. /ssp fluten oder sich in einem anderen Browser-Tab als Admin bei /aiconsole einloggen).
  2. Sende mit hoher Parallelität headerfreie SOAP-Bodies an /ac-iasp-backend-jaxws/UserManager oder andere EJB-gestützte JAX-WS-Endpunkte; jeder Treffer, der einen “infizierten” Thread wiederverwendet, läuft mit erhöhtem Subject.
  3. Wiederholen, bis privilegierte Antworten zurückkommen; Keep-Alive-Verbindungen und große Worker-Pools wiederverwenden, um die Wahrscheinlichkeit der Thread-Wiederverwendung zu maximieren.
  • Handler- und Prozessfluss-Höhepunkte:
  • LoginHandlerChain.xmlLoginHandler.handleMessage() unmarshalt mySubjectHeader und speichert das Subject in SubjectHolder (ein statisches ThreadLocal).
  • ProcessManager.triggerProcess() injiziert später SubjectHolder.getSubject() in Geschäftsprozesse, sodass fehlende Header zu stale Identitäten führen.
  • In-field PoC aus dem Advisory verwendet einen zweistufigen SOAP-Abuse: zuerst getUsers, um info zu leaken, dann createUser + importCredential, um einen Rogue-Admin zu platzieren, wenn der privilegierte Thread trifft.

Validierung des Bugs

  • Hänge JDWP (-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n) oder ähnliche Debugging-Hooks an, um den Inhalt des ThreadLocal vor und nach jedem Aufruf zu beobachten und zu bestätigen, dass eine nicht-authentifizierte Anfrage ein vorheriges Administrator-Subject geerbt hat.
  • In Produktions-Appliances kann man auch mit JFR oder BTrace instrumentieren, um SubjectHolder.getSubject() pro Anfrage zu dumpen und die headerfreie Wiederverwendung zu verifizieren.

References

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks