JWT 安全指南:漏洞赏金猎人的实战攻略(第二部分)

78 阅读3分钟

官网:http://securitytech.cc/

JWT 安全指南:漏洞赏金猎人的实战攻略(第二部分)

大家好!在上一篇 JWT 文章得到热烈反响之后,我带着 第二部分 回来了。正如我之前所说,这将会是一系列与漏洞赏金(Bug Bounty)相关的 JWT 安全文章。读完并实际操作完整个系列之后,你将在 JWT 上进入“野兽模式”。因为我会展示真实网站逻辑中的实例,而不是一些“玩具漏洞网站”。我们会在真实逻辑场景中学习,这些逻辑在大多数 Web 应用中都会使用。 所以,抛开干扰,集中注意力 —— 或许一笔大赏金正等着你。 所以我再问你一次:你——准——备——好——了——吗?

在上一篇文章中,我们学习了通过将 JWT 的算法降级为 none 的方式进行攻击(我就不重复了,没看过的请点这里:[传送门]。

那么,如果这种方法行不通怎么办?

接下来,我们来聊一种非常常见的技术。虽然这种方式不一定直接带来赏金,但它的危害等级是 9(严重)。那么,是什么呢?


弱对称密钥(Weak Symmetric Secrets)

可能很多人会说:“嘿,这个方法我知道,没意思,行不通。” 先别急,耐心看完。

顾名思义,这是尝试找到算法的 secret(密钥) 的一种技术。简单说,就是找出算法的“密码”。

怎么找?

答案很简单 —— 暴力破解(brute force)。下面稍微技术一点。

当 JWT 使用 对称签名算法 时,JWT 的安全性依赖于所用 secret 的强度与熵。如果 secret 很弱,就有可能通过离线破解找出它。一旦 secret 泄露,你就能修改 JWT 中的 claims,并使用该 secret 重新签名,生成一个有效的 Token。

操作步骤:

  1. 将 JWT 保存到一个名为 jwt.txt 的文件中。
    1. 下载常见的 JWT secret 字典,例如:
wget https://raw.githubusercontent.com/wallarm/jwt-secrets/master/jwt.secrets.list
  1. 使用 Hashcat 破解:

    hashcat -m 16500 -a 0 jwt.txt jwt.secrets.list
    

如果你能破解出来,那么恭喜你 —— 发财了 🎉。

因为一旦拿到 secret,就能随意篡改 JWT 中的参数,然后用这个 secret 生成签名,依然是有效的。


签名算法混淆(Signature Algorithm Confusion)

这一部分有点烧脑,请注意听。我会尽量讲清楚。

JWT 的签名算法大致分为两类:

  • 对称算法:只有一个密钥,用于加密和解密。
  • 非对称算法:有两个密钥 —— 私钥(加密)和公钥(解密)。

关键点:

如果 JWT 使用的是非对称算法(如 RS256),有时可能被降级为 HS256。 一些库在处理时,会将 公钥 当作 HS256 的 secret。

而公钥通常并不敏感,甚至可能被公开获取。这样一来,攻击者就能使用公钥生成合法签名 —— 只需把算法从 RS256 改为 HS256

有些情况下,公钥甚至会直接写在 JWT 的 claims 中,或在接口中能拿到。

攻击流程:

  1. 将算法从 RS256 改为 HS256
  2. 使用 公钥 作为 secret 来签名 JWT。
  3. 生成一个修改了 claims 的有效 JWT。

简化解释:

比如我们在 jwt.io 解码时看到算法是 RS256(非对称算法)。 如果能改成 HS256,就变成对称算法了。 而这时候,公钥本身就会作为密钥使用。

换句话说,公钥 = 签名密钥

那么,问题来了:公钥从哪找?

方法有很多,比如尝试请求 JWT 的签发接口(GET 请求),有时能拿到公钥。还有其他方式,这里不展开了(你可以去 Google,或者在评论区留言,我可以专门写一篇文章讲)。


总结

本文讲了两种 JWT 攻击手法:

  1. 弱对称密钥 —— 使用字典+暴力破解找出 secret。
  2. 签名算法混淆 —— 将 RS256 降级为 HS256,使用公钥签名。

后面还有一些方法,留到 第三部分 再讲。

在那之前 —— 继续狩猎吧!