SOAP/JAX-WS ThreadLocal Authentication Bypass

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

TL;DR

  • कुछ middleware chains authenticated Subject/Principal को एक static ThreadLocal में संग्रहीत करते हैं और केवल तब उसे रीफ्रेश करते हैं जब कोई proprietary SOAP header आता है।
  • क्योंकि WebLogic/JBoss/GlassFish worker थ्रेड्स को recycle करते हैं, उस header को हटाने से थ्रेड द्वारा प्रोसेस किया गया आख़िरी privileged Subject चुपचाप फिर से उपयोग हो जाता है।
  • header-मुक्त परंतु सही-निर्मित SOAP बॉडीज़ के साथ vulnerable endpoint पर लगातार अनुरोध भेजें जब तक कि कोई पुन: उपयोग की गई थ्रेड आपको चोरी किया गया administrator context न दे।
  • 2025 HID ActivID/IASP (HID-PSA-2025-002) एक वास्तविक उदाहरण है: JAX-WS handler एक SubjectHolder ThreadLocal को cache करता है, जिससे unauthenticated SOAP कॉल्स पिछले console/SSP अनुरोधों द्वारा सेट की गयी identity को inherit कर लेती हैं।

Root Cause

निम्नलिखित जैसे handlers केवल तब ही thread-local identity को overwrite करते हैं जब custom header मौजूद हो, इसलिए पिछले request का context जीवित रह जाता है:

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. reverse proxy / routing नियमों को सूचीबद्ध करें ताकि छिपे हुए SOAP ट्री मिल सकें जो ?wsdl को ब्लॉक कर सकते हैं पर POSTs स्वीकार करते हैं (उन्हें 80,443 - Pentesting Web Methodology के flow के साथ मैप करें)।
  2. EAR/WAR/EJB artifacts को unpack करें (unzip *.ear) और application.xml, web.xml, @WebService annotations, और handler chains (जैसे, LoginHandlerChain.xml) को inspect करें ताकि handler class, SOAP header QName, और backing EJB नाम पता चल सकें।
  3. अगर metadata गायब है, तो संभावित ServiceName?wsdl paths को brute-force करें या अस्थायी रूप से lab proxies को relax करें, फिर जो भी recovered WSDL मिले उसे Burp Suite Wsdler जैसे tooling में import करके baseline envelopes generate करें।
  4. handler स्रोतों की समीक्षा करें ThreadLocal keepers (उदा., SubjectHolder.setSubject()) के लिए जो authentication header गायब या malformed होने पर कभी clear नहीं होते।

Exploitation

  1. वैध request के साथ proprietary header भेजें ताकि सामान्य response codes और invalid tokens के लिए उपयोग की जाने वाली किसी भी error का पता चल सके।
  2. वही SOAP body header हटाकर पुनः भेजें। XML को well-formed रखें और आवश्यक namespaces का सम्मान करें ताकि handler साफ़ तरीके से exit करे।
  3. request को loop करें; जब यह उस thread पर पहुंचे जो पहले privileged action execute कर चुका है, तो पुन: उपयोग किया गया Subject protected operations जैसे user या credential managers को unlock कर देता है।
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 केस स्टडी (HID-PSA-2025-002)

  • Synacktiv ने दिखाया कि JAX-WS LoginHandler ActivID 8.6–8.7 में mySubjectHeader SOAP हेडर मौजूद होने पर या console/SSP ट्रैफिक प्रमाणीकृत होने पर SubjectHolder.subject सेट करता है, लेकिन जब हेडर अनुपस्थित होता है तो इसे कभी साफ़ नहीं करता।
  • उसी worker thread पर किसी भी बाद की SOAP कॉल जिसमें हेडर नहीं है, उस cached Subject को विरासत में ले लेती है, जिससे UserManager या CredentialManager जैसे endpoints के माध्यम से बिना प्रमाणीकरण के administrator users बनाना या credential import करना संभव हो जाता है।
  • देखा गया विश्वसनीय शोषण पैटर्न:
  1. कई threads पर एक प्रमाणीकृत context ट्रिगर करें (उदा., /ssp को स्पैम करें या दूसरे ब्राउज़र टैब में admin के रूप में /aiconsole में लॉगिन करें)।
  2. उच्च समानांतरता के साथ हेडर-रहित SOAP बॉडीज़ को /ac-iasp-backend-jaxws/UserManager या अन्य EJB-backed JAX-WS endpoints पर flood करें; हर हिट जो एक “infected” थ्रेड को पुन: उपयोग करता है, वह elevated Subject के साथ निष्पादित होता है।
  3. तब तक दोहराएँ जब तक privileged responses वापस न मिलें; Keep-Alive connections और बड़े worker pools का पुन: उपयोग करें ताकि thread reuse की संभावना अधिकतम हो।
  • Handler और process फ्लो के मुख्य बिंदु:
  • LoginHandlerChain.xmlLoginHandler.handleMessage() mySubjectHeader को unmarshall करता है और Subject को SubjectHolder (एक static ThreadLocal) में स्टोर करता है।
  • बाद में ProcessManager.triggerProcess() business processes में SubjectHolder.getSubject() इंजेक्ट करता है, इसलिए मिसिंग हेडर stale identities को बरकरार छोड़ देते हैं।
  • सलाह में दिए गए in-field PoC में दो-स्टेप SOAP दुरुपयोग का उपयोग होता है: पहले getUsers से जानकारी leak करना, फिर जब privileged thread सक्रिय हो तब createUser + importCredential से एक rogue admin प्लांट करना।

बग का सत्यापन

  • JDWP संलग्न करें (-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n) या समान debugging hooks का उपयोग करें ताकि प्रत्येक कॉल से पहले और बाद में ThreadLocal सामग्री देखी जा सके, यह पुष्टि करते हुए कि एक बिना प्रमाणीकरण अनुरोध ने पहले के administrator Subject को विरासत में लिया था।
  • प्रोडक्शन appliances में आप JFR या BTrace के साथ भी instrumentation कर सकते हैं ताकि प्रति request SubjectHolder.getSubject() dump करके header-less reuse को सत्यापित किया जा सके।

References

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें