SOAP/JAX-WS ThreadLocal Authentication Bypass

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

TL;DR

  • Algumas cadeias de middleware armazenam o Subject/Principal autenticado dentro de um ThreadLocal estático e só o atualizam quando um cabeçalho SOAP proprietário chega.
  • Porque WebLogic/JBoss/GlassFish reciclam worker threads, remover esse cabeçalho faz com que o último Subject privilegiado processado pela thread seja reutilizado silenciosamente.
  • Forceie o endpoint vulnerável com bodies SOAP sem cabeçalho, porém bem-formados, até que uma thread reutilizada lhe conceda o contexto de administrador roubado.

Root Cause

Handlers semelhantes ao seguinte apenas sobrescrevem a identidade thread-local quando o cabeçalho customizado está presente, então o contexto da requisição 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;
}

Reconhecimento

  1. Enumere as regras de reverse proxy / roteamento para localizar árvores SOAP ocultas que podem bloquear ?wsdl mas aceitar POSTs (mapeie-as junto ao fluxo em 80,443 - Pentesting Web Methodology).
  2. Descompacte os artefatos EAR/WAR/EJB (unzip *.ear) e inspecione application.xml, web.xml, anotações @WebService e handler chains (e.g., LoginHandlerChain.xml) para descobrir a classe do handler, o QName do header SOAP e os nomes dos EJBs de suporte.
  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 to generate baseline envelopes.
  4. Revise as fontes dos handlers em busca de mantenedores ThreadLocal (e.g., SubjectHolder.setSubject()) que nunca são limpos quando o cabeçalho de autenticação está ausente ou malformado.

Exploração

  1. Envie uma requisição válida com o cabeçalho proprietário para aprender os códigos de resposta normais e qualquer erro usado para tokens inválidos.
  2. Reenvie o mesmo body SOAP omitindo o cabeçalho. Mantenha o XML bem-formado e respeite os namespaces exigidos para que o handler saia limpo.
  3. Faça um loop da requisição; quando ela cair em uma thread que executou anteriormente uma ação privilegiada, o reutilizado Subject desbloqueia operações protegidas como gerenciadores de usuários ou credenciais.
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>

Validando o Bug

  • Anexe JDWP (-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n) ou ganchos de depuração similares para observar o conteúdo de ThreadLocal antes e depois de cada chamada, confirmando que uma requisição não autenticada herdou um Subject de administrador anterior.

Referências

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks