SOAP/JAX-WS ThreadLocal Authentication Bypass

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

TL;DR

  • Algunas cadenas de middleware almacenan el Subject/Principal autenticado dentro de un ThreadLocal estático y solo lo actualizan cuando llega un encabezado SOAP propietario.
  • Debido a que WebLogic/JBoss/GlassFish reciclan los hilos de trabajo, la ausencia de ese encabezado provoca que el último Subject privilegiado procesado por el hilo sea reutilizado silenciosamente.
  • Satura el endpoint vulnerable con cuerpos SOAP bien formados pero sin encabezado hasta que un hilo reutilizado te conceda el contexto de administrador robado.
  • 2025 HID ActivID/IASP (HID-PSA-2025-002) es un caso real: el handler JAX-WS almacena en caché un SubjectHolder ThreadLocal, permitiendo que llamadas SOAP no autenticadas hereden la identidad establecida por solicitudes previas desde la consola/SSP.

Causa raíz

Handlers similares al siguiente solo sobrescriben la identidad a nivel de hilo cuando el encabezado personalizado está presente, por lo que el contexto de la solicitud anterior sobrevive:

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. Enumera las reglas de reverse proxy / routing para localizar árboles SOAP ocultos que puedan bloquear ?wsdl pero aceptar POSTs (mapeálos junto al flujo en 80,443 - Pentesting Web Methodology).
  2. Desempaqueta los artefactos EAR/WAR/EJB (unzip *.ear) e inspecciona application.xml, web.xml, las anotaciones @WebService y handler chains (p. ej., LoginHandlerChain.xml) para descubrir la clase handler, el QName del encabezado SOAP y los nombres de los EJB de respaldo.
  3. Si falta metadata, fuerza rutas probables ServiceName?wsdl o relaja temporalmente los proxies del laboratorio, luego importa cualquier WSDL recuperado en herramientas como Burp Suite Wsdler para generar plantillas de SOAP Envelope.
  4. Revisa las fuentes del handler buscando ThreadLocal keepers (p. ej., SubjectHolder.setSubject()) que nunca se limpian cuando falta el encabezado de autenticación o está mal formado.

Exploitation

  1. Envía una petición válida con el encabezado propietario para conocer los códigos de respuesta normales y cualquier error usado para tokens inválidos.
  2. Reenvía el mismo body SOAP omitiendo el header. Mantén el XML bien formado y respeta los namespaces requeridos para que el handler termine limpiamente.
  3. Bucle la petición; cuando caiga en un hilo que previamente ejecutó una acción privilegiada, el Subject reutilizado desbloquea operaciones protegidas como gestores de usuarios o de credenciales.
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 estudio de caso (HID-PSA-2025-002)

  • Synacktiv mostró que el JAX-WS LoginHandler en ActivID 8.6–8.7 establece SubjectHolder.subject cuando está presente un encabezado SOAP mySubjectHeader o cuando el tráfico de la consola/SSP se autentica, pero nunca lo borra cuando el encabezado está ausente.
  • Cualquier llamada SOAP subsiguiente que carezca del encabezado en el mismo hilo de trabajo hereda ese Subject en caché, lo que permite la creación no autenticada de usuarios administradores o la importación de credenciales a través de endpoints como UserManager o CredentialManager.
  • Patrón de explotación observado de forma confiable:
  1. Generar un contexto autenticado en muchos hilos (p. ej., spamear /ssp o iniciar sesión en /aiconsole como admin en otra pestaña del navegador).
  2. Enviar en masa cuerpos SOAP sin encabezado a /ac-iasp-backend-jaxws/UserManager u otros endpoints JAX-WS respaldados por EJB con alto paralelismo; cada petición que reutilice un hilo “infectado” se ejecuta con un Subject elevado.
  3. Repetir hasta que se reciban respuestas privilegiadas; reutilizar conexiones Keep-Alive y pools de trabajadores grandes para maximizar la probabilidad de reutilización de hilos.
  • Puntos destacados del handler y del flujo de proceso:
  • LoginHandlerChain.xmlLoginHandler.handleMessage() desempaqueta (unmarshals) mySubjectHeader y almacena el Subject en SubjectHolder (un ThreadLocal estático).
  • ProcessManager.triggerProcess() luego inyecta SubjectHolder.getSubject() en los procesos de negocio, por lo que los encabezados ausentes dejan identidades obsoletas intactas.
  • El PoC en campo del advisory usa un abuso SOAP en dos pasos: primero getUsers para leak info, luego createUser + importCredential para plantar un administrador malicioso cuando el hilo privilegiado recibe la petición.

Validación del bug

  • Adjuntar JDWP (-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n) u hooks de depuración similares para observar el contenido del ThreadLocal antes y después de cada llamada, confirmando que una petición no autenticada heredó un Subject de administrador previo.
  • En appliances de producción también se puede instrumentar con JFR o BTrace para volcar SubjectHolder.getSubject() por petición, verificando la reutilización sin encabezado.

References

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks