SOAP/JAX-WS ThreadLocal Authentication Bypass

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

TL;DR

  • Niektóre łańcuchy middleware przechowują uwierzytelniony Subject/Principal wewnątrz statycznego ThreadLocal i odświeżają go tylko, gdy pojawi się własny nagłówek SOAP.
  • Ponieważ WebLogic/JBoss/GlassFish ponownie wykorzystują wątki robocze, pominięcie tego nagłówka powoduje ciche ponowne użycie ostatniego uprzywilejowanego Subject przetworzonego przez wątek.
  • Zaatakuj podatny endpoint wielokrotnymi żądaniami SOAP bez nagłówków, ale poprawnie sformatowanymi, aż ponownie użyty wątek przyzna ci skradziony kontekst administratora.
  • 2025 HID ActivID/IASP (HID-PSA-2025-002) jest rzeczywistym przykładem: handler JAX-WS buforuje SubjectHolder ThreadLocal, pozwalając nieuwierzytelnionym wywołaniom SOAP odziedziczyć tożsamość ustawioną przez poprzednie żądania konsoli/SSP.

Przyczyna

Handlery podobne do poniższych nadpisują tożsamość w ThreadLocal tylko wtedy, gdy obecny jest niestandardowy nagłówek, więc kontekst poprzedniego żądania przetrwa:

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. Wyszukaj reguły reverse proxy / routingu, aby zlokalizować ukryte drzewa SOAP, które mogą blokować ?wsdl, lecz akceptować POSTs (zmapuj je obok flow w 80,443 - Pentesting Web Methodology).
  2. Rozpakuj artefakty EAR/WAR/EJB (unzip *.ear) i przejrzyj application.xml, web.xml, adnotacje @WebService oraz handler chains (np. LoginHandlerChain.xml), aby zidentyfikować klasę handlera, SOAP header QName i nazwy odpowiadających EJB.
  3. Jeśli brak metadanych, przeprowadź brute-force prawdopodobnych ścieżek ServiceName?wsdl lub tymczasowo poluzuj lab proxies, a następnie zaimportuj odzyskane WSDL do narzędzi takich jak Burp Suite Wsdler by wygenerować podstawowe koperty SOAP.
  4. Przejrzyj źródła handlera pod kątem ThreadLocal keeperów (np. SubjectHolder.setSubject()), które nigdy nie są czyszczone, gdy nagłówek uwierzytelniający jest nieobecny lub niepoprawny.

Exploitation

  1. Wyślij poprawne żądanie z proprietarnym nagłówkiem, aby poznać normalne kody odpowiedzi oraz błędy używane dla nieprawidłowych tokenów.
  2. Wyślij ponownie tę samą treść SOAP, pomijając nagłówek. Zachowaj dobrze uformowany XML i respektuj wymagane przestrzenie nazw, aby handler zakończył się poprawnie.
  3. Powtarzaj żądanie w pętli; gdy trafi ono na wątek, który wcześniej wykonał uprzywilejowaną operację, ponownie użyty Subject odblokowuje chronione operacje, np. menedżery użytkowników lub poświadczeń.
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 studium przypadku (HID-PSA-2025-002)

  • Synacktiv wykazał, że JAX-WS LoginHandler w ActivID 8.6–8.7 ustawia SubjectHolder.subject, gdy nagłówek SOAP mySubjectHeader jest obecny lub gdy ruch z konsoli/SSP się uwierzytelnia, ale nigdy go nie czyści, gdy nagłówek jest nieobecny.
  • Każde kolejne wywołanie SOAP pozbawione nagłówka na tym samym wątku roboczym dziedziczy ten zapisany w pamięci Subject, co pozwala na nieautoryzowane tworzenie kont administratora lub import poświadczeń przez endpointy takie jak UserManager lub CredentialManager.
  • Zaobserwowano wiarygodny wzorzec eksploatacji:
  1. Wywołać uwierzytelniony kontekst na wielu wątkach (np. spamować /ssp lub zalogować się do /aiconsole jako admin w innej karcie przeglądarki).
  2. Zalewać ciała SOAP bez nagłówka do /ac-iasp-backend-jaxws/UserManager lub innych EJB-backed JAX-WS endpointów z wysoką równoległością; każde żądanie, które ponownie wykorzysta “zainfekowany” wątek, wykona się z podniesionym Subject.
  3. Powtarzać aż do otrzymania uprzywilejowanych odpowiedzi; ponownie wykorzystywać połączenia Keep-Alive i duże pule wątków roboczych, aby maksymalizować prawdopodobieństwo ponownego użycia wątku.
  • Najważniejsze elementy handlera i przepływu procesu:
  • LoginHandlerChain.xmlLoginHandler.handleMessage() unmarshaluje mySubjectHeader i zapisuje Subject w SubjectHolder (statyczny ThreadLocal).
  • ProcessManager.triggerProcess() później wstrzykuje SubjectHolder.getSubject() do procesów biznesowych, więc brakujące nagłówki pozostawiają zaległe tożsamości niezmienione.
  • Polowy PoC z advisory używa dwuetapowego nadużycia SOAP: najpierw getUsers to leak info, następnie createUser + importCredential aby wstawić złośliwego administratora gdy trafiony zostanie uprzywilejowany wątek.

Weryfikacja błędu

  • Dołącz JDWP (-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n) lub podobne debugujące haki, aby obserwować zawartość ThreadLocal przed i po każdym wywołaniu, potwierdzając, że nieautoryzowane żądanie odziedziczyło wcześniejszy administrator Subject.
  • W urządzeniach produkcyjnych możesz też instrumentować za pomocą JFR lub BTrace, aby zrzucać SubjectHolder.getSubject() dla każdego żądania, weryfikując ponowne użycie bez nagłówka.

Odniesienia

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks