SOAP/JAX-WS ThreadLocal Authentication Bypass

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

TL;DR

  • Деякі middleware-ланцюги зберігають автентифікований Subject/Principal всередині статичного ThreadLocal і оновлюють його тільки коли надходить власний SOAP-заголовок.
  • Через те, що WebLogic/JBoss/GlassFish повторно використовують робочі потоки, відсутність цього заголовка спричиняє непомітне повторне використання останнього привілейованого Subject, обробленого потоком.
  • Навантажуйте вразливу endpoint запитами без заголовків, але з коректними SOAP-телами, поки повторно використаний потік не надасть вам викрадений контекст адміністратора.
  • 2025 HID ActivID/IASP (HID-PSA-2025-002) — реальний випадок: JAX-WS handler кешує SubjectHolder ThreadLocal, дозволяючи неавтентифікованим SOAP-викликам наслідувати ідентичність, встановлену попередніми console/SSP-запитами.

Основна причина

Handlers similar to the following only overwrite the thread-local identity when the custom header is present, so the previous request’s context survives:

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 / маршрутизації, щоб знайти приховані SOAP дерева, які можуть блокувати ?wsdl, але приймати POSTs (відобразіть їх паралельно з потоком у 80,443 - Pentesting Web Methodology).
  2. Розпакуйте артефакти EAR/WAR/EJB (unzip *.ear) і проаналізуйте application.xml, web.xml, анотації @WebService та handler chains (наприклад, LoginHandlerChain.xml), щоб виявити клас обробника, SOAP header QName і імена бекендних EJB.
  3. Якщо метадані відсутні, перебирайте ймовірні шляхи ServiceName?wsdl або тимчасово ослабте лабораторні проксі, після чого імпортуйте будь-який відновлений WSDL у інструменти на кшталт Burp Suite Wsdler для генерації базових SOAP-envelopes.
  4. Перегляньте вихідники обробника на наявність ThreadLocal-зберігачів (наприклад, SubjectHolder.setSubject()), які ніколи не очищуються, коли аутентифікаційний заголовок відсутній або пошкоджений.

Exploitation

  1. Надішліть дійсний запит з пропрієтарним заголовком, щоб дізнатися звичні коди відповіді та помилку, що використовується для недійсних токенів.
  2. Повторіть те саме тіло SOAP, пропускаючи заголовок. Тримайте XML коректним і дотримуйтеся необхідних просторів імен, щоб обробник коректно завершив роботу.
  3. Зацикліть запит; коли він потрапить на потік, який раніше виконав привілейовану дію, повторно використаний Subject розблокує захищені операції, такі як менеджери користувачів або менеджери облікових даних.
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 case study (HID-PSA-2025-002)

  • Synacktiv продемонстрував, що JAX-WS LoginHandler в ActivID 8.6–8.7 встановлює SubjectHolder.subject, коли присутній SOAP-заголовок mySubjectHeader або коли трафік консолі/SSP автентифікується, але ніколи не очищує його, коли заголовок відсутній.
  • Будь-який наступний SOAP-виклик без цього заголовка на тому ж worker thread успадковує той кешований Subject, що дозволяє неавтентифіковане створення administrator users або імпорт credentials через endpoints, такі як UserManager або CredentialManager.
  • Надійний шаблон експлуатації, що спостерігався:
  1. Створити автентифікований контекст на багатьох threads (наприклад, спамити /ssp або залогінитись у /aiconsole як admin в іншій вкладці браузера).
  2. Масово надсилати SOAP-тела без заголовків до /ac-iasp-backend-jaxws/UserManager або інших EJB-backed JAX-WS endpoints з високою паралельністю; кожний hit, що повторно використовує “інфікований” thread, виконується з підвищеним Subject.
  3. Повторювати до отримання привілейованих відповідей; повторно використовувати Keep-Alive connections і великі worker pools, щоб максимізувати ймовірність повторного використання thread-ів.
  • Ключові моменти роботи handler-ів і процесу:
  • LoginHandlerChain.xmlLoginHandler.handleMessage() десеріалізує (unmarshals) mySubjectHeader і зберігає Subject у SubjectHolder (статичний ThreadLocal).
  • ProcessManager.triggerProcess() пізніше вставляє SubjectHolder.getSubject() у бізнес-процеси, тому відсутні заголовки залишають застарілі ідентичності неочищеними.
  • PoC з advisory у полі використовує двоетапне зловживання SOAP: спочатку getUsers для leak інформації, потім createUser + importCredential щоб створити зловмисного admin коли привілейований thread буде використано.

Перевірка бага

  • Підключіть JDWP (-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n) або схожі debugging hooks, щоб спостерігати вміст ThreadLocal до і після кожного виклику, підтверджуючи, що неавтентифікований запит успадкував попередній administrator Subject.
  • У production appliances ви також можете інструментувати за допомогою JFR або BTrace, щоб дампити SubjectHolder.getSubject() для кожного запиту, перевіряючи повторне використання без заголовка.

References

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks