利用X509证书攻击JWT:实战演练与Burp扩展工具

本文详细解析如何利用JWT中的x5c和x5u头参数,通过X509证书篡改令牌签名,实现权限提升。包含漏洞原理、PoC演示、Burp扩展工具使用及防御建议,适合渗透测试和应用安全研究人员参考。

攻击JWT使用X509证书

1.1 设置

为了开始此攻击,我们需要一个易受攻击的应用程序进行测试。我为此在Flask中创建了一个易受攻击的API。

https://github.com/Tsynack/JWT_X509_Re-Signer/tree/main/Example%20API

图1 - 运行示例API

为了使测试更容易,我还构建了一个自定义的Burp扩展,允许修改头和声明。该扩展还可用于重新签名令牌。您可以在此处找到扩展:

https://github.com/Tsynack/JWT_X509_Re-Signer/tree/main/Burp%20Extension

注意: 该扩展依赖于在Burp的扩展设置中设置Jython。

要安装扩展,导航到Extensions > Add > Extension Type: Python > 并选择JWT_x509_Re-Sign.py文件。

图2 - 加载JWT重新签名器

一旦扩展加载,任何包含JWS的Burp HTTP历史或Repeater中的请求都应有一个标记为“重新签名JWT”的选项卡。

图3 - 扩展已安装

为了执行此攻击,我们最后需要的是一个X509私钥用于签名令牌,以及相关的证书,以便服务器可以验证签名。使用OpenSSL,可以通过以下命令完成:

1
openssl req -newkey rsa:2048 -nodes -keyout private_key.pem -x509 -days 365 -out cert.pem

1.2 攻击剖析

快速回顾一下,JWS包含三个部分:

  • 头(Header) - 包含关于签名如何生成的详细信息,并可能包含JWS内容的详细信息
  • 声明(Claims) - 包含关于发生的认证过程的详细信息。一些示例声明包括:
    • Iat(签发时间) - JWS生成时的纪元时间
    • Exp(过期时间) - 服务器不应再接受令牌的纪元时间
    • Sub(主题) – 与令牌关联的用户
  • 签名(Signature) - 声明与头中列出的算法结合生成签名。这确保令牌在服务器处理请求之前未被篡改。

图4 - 示例令牌结构
图5 - 示例头
图6 - 示例声明

在JWS的RFC中,概述了两个可选的头参数:

  • x5c - 包含X509公钥证书或证书链
  • x5u - 指向X509公钥证书或证书链的URI

公钥是服务器验证令牌签名并确定声明是否被篡改的方式。如果服务器使用这些参数的值来验证签名,我们有机会修改声明并用我们自己的密钥签名令牌。

1.3 概念验证

使用前面提到的示例API,我们将发送几个请求到Burp的Repeater以篡改令牌。在示例API文件夹中,我包含了一个API_example_requests.txt,其中包含用于生成登录和验证请求的curl命令。您应该能够复制并粘贴登录命令,并在响应中接收令牌。令牌需要复制到验证命令中。

图7 - API登录
图8 - API验证请求

如果一切正常,Burp的代理历史中应记录两个请求。右键单击/verify请求并将其发送到Repeater。

在Repeater中,导航到“重新签名JWT”选项卡。按下解码按钮将对令牌头和声明进行base64解码。对这些值的任何修改将在令牌重新签名后反映。首先将sub声明修改为root。

图9 - 解码和修改声明

对于第一次攻击,我们将公钥证书直接嵌入到x5c参数中。为此,您需要导入之前使用OpenSSL生成的X509私钥和证书。

图10 - 导入私钥和证书

由于我们将证书嵌入到令牌中,选择使用x5c头重新签名令牌并点击Attack!请求中的令牌将自动更新为新签名的令牌。发送请求应返回200 OK,表示更新后的令牌已被服务器接受。

图11 - 重新签名的令牌被服务器接受

如果您做到了这一步,恭喜您通过用自己的私钥签名令牌成功利用了漏洞!

1.4 攻击x5u

x5u头不是将证书内容直接嵌入到令牌中,而是将服务器指向可以找到内容的URI。为了利用这一点,我将cert.pem托管在我的Web服务器上,并将在扩展中的相应字段添加URL。

确保将重新签名的方法更新为使用x5u头,并点击Attack!当请求发送时,您托管证书的Web服务器应收到对cert.pem的请求,表明API在验证签名时已外部交互。

图12 - 访问日志显示外部交互

API响应应显示200 OK,表示签名和声明已被接受。

图13 - 利用x5u头

1.5 结论

对于每个已识别的头,问题是服务器信任提供的证书来验证令牌签名。作为攻击者,我们可以控制头的值,因此可以提供我们自己的证书。最终结果是一个被破坏的令牌,允许任何人更改声明中的值以冒充其他用户或执行权限提升。

作为开发者,检查您的令牌验证流程。即使您在签发令牌时未显式使用这些头,服务器是否会接受头值并根据提供的证书验证签名?实施代码以确保仅使用预期的证书来验证令牌签名。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计