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

摘要

  • 一些中间件链将经过认证的 Subject/Principal 存储在静态的 ThreadLocal 中,并且仅在接收到专有的 SOAP header 时才刷新它。
  • 由于 WebLogic/JBoss/GlassFish 会回收工作线程,省略该 header 会导致线程上一次处理的具有特权的 Subject 被静默重用。
  • 用缺少 header 但格式正确的 SOAP body 持续轰击易受攻击的端点,直到被重用的线程授予你被盗用的管理员上下文。
  • 2025 年的 HID ActivID/IASP (HID-PSA-2025-002) 是一个真实例子:JAX-WS handler 缓存了一个 SubjectHolder ThreadLocal,让未认证的 SOAP 调用继承之前 console/SSP 请求设置的身份。

根本原因

类似下面的 handlers 只在自定义 header 存在时才覆盖线程本地的身份,因此先前请求的上下文会保留:

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;
}

侦察

  1. 枚举 reverse proxy / routing 规则以定位可能屏蔽 ?wsdl 但接受 POSTs 的隐藏 SOAP 树(将它们与流程在 80,443 - Pentesting Web Methodology 中并列映射)。
  2. 解压 EAR/WAR/EJB 工件 (unzip *.ear) 并检查 application.xmlweb.xml@WebService 注解和处理器链(例如 LoginHandlerChain.xml),以发现 handler 类、SOAP header 的 QName 以及后端 EJB 名称。
  3. 如果元数据缺失,对可能的 ServiceName?wsdl 路径进行暴力枚举或临时放宽实验室代理,然后将恢复的 WSDL 导入到像 Burp Suite Wsdler 这样的工具中以生成基线 SOAP envelopes。
  4. 检查 handler 源码,查找在认证 header 缺失或格式错误时未被清理的 ThreadLocal 持有者(例如 SubjectHolder.setSubject())。

利用

  1. 发送包含专有 header 的有效请求,以了解正常的响应码以及针对无效 token 的错误返回。
  2. 在省略 header 的情况下重发相同的 SOAP body。保持 XML 格式良好并遵守所需命名空间,以便 handler 能干净地退出。
  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 案例研究 (HID-PSA-2025-002)

  • Synacktiv 发现 JAX-WS 的 LoginHandler 在 ActivID 8.6–8.7 中,当存在 mySubjectHeader SOAP header 或 console/SSP 流量完成认证时,会将 SubjectHolder.subject 设置为该身份,但当 header 不存在时从不清除它。
  • 随后的任何在同一 worker 线程上且缺少该 header 的 SOAP 调用都会继承该缓存的 Subject,从而允许未认证情况下通过诸如 UserManagerCredentialManager 等端点创建管理员用户或导入凭据。
  • 观察到的可靠利用模式:
    1. 在大量线程上触发已认证上下文(例如,在另一个浏览器标签页向 /ssp 发送大量请求或以管理员身份登录 /aiconsole)。
    2. 以高并发向 /ac-iasp-backend-jaxws/UserManager 或其他由 EJB 支持的 JAX-WS 端点发送不带 header 的 SOAP 请求洪流;每次命中复用到“被感染”的线程时都会以提升的 Subject 执行。
    3. 重复直到返回特权响应;重用 Keep-Alive 连接和较大的 worker 池以最大化线程复用概率。
  • Handler 与流程要点:
    • LoginHandlerChain.xmlLoginHandler.handleMessage() 反序列化 mySubjectHeader 并将 Subject 存储到 SubjectHolder(一个静态的 ThreadLocal)。
    • ProcessManager.triggerProcess() 随后将 SubjectHolder.getSubject() 注入到业务流程中,所以缺失 header 会导致陈旧身份保持不变。
  • 来自 advisory 的现场 PoC 使用两步 SOAP 滥用:先用 getUsers leak 信息,然后在特权线程被复用时用 createUser + importCredential 植入 rogue admin。

验证该漏洞

  • 附加 JDWP(-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=n)或类似调试钩子,观察每次调用前后 ThreadLocal 的内容,确认未认证请求继承了先前的管理员 Subject
  • 在生产设备上也可以使用 JFR 或 BTrace 对每次请求转储 SubjectHolder.getSubject(),以验证无 header 的复用情况。

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