JWT 弱密钥:Hashcat 与 JWT Editor 实战笔记
记录 JWT 弱密钥靶场中的签名原理、Hashcat 字典测试与结果查看,以及 JWT Editor 导入密钥和重新签名的流程。
本文记录授权靶场中的学习过程。示例中的弱密钥与身份字段用于说明原理,不代表所有应用都使用相同配置。
一、核心知识逻辑:为什么要这么做?
JWT 的常见签名形式由三部分组成:Header.Payload.Signature。
以 HS256 为例,签名计算可以写成:
signingInput = Base64URL(Header 的 UTF-8 字节) + "." + Base64URL(Payload 的 UTF-8 字节)
Signature = Base64URL(HMAC-SHA256(key=Secret, message=signingInput))
这里的 Base64URL 编码省略末尾的 = 填充。校验已有 Token 时,应使用它原有的前两段作为签名输入,不能把 JSON 重新排版后再比较签名。
- 致命缺陷: 如果服务端使用了弱密钥,例如
123456、dragon,就可能通过字典猜出这个 Secret。弱密钥不等于一定能被当前字典命中。 - 权限提升: 找到 Secret 后,可以修改 Payload,并用相同密钥重新签名。例如将
"role":"user"改为"role":"admin"。能否获得管理员权限,取决于后端是否信任该字段,以及是否还有其他身份、权限和有效期校验。
二、工具实战手法:两种模式
1. Burp JWT Editor:手工验证与重新签名
- 在
JWT Editor或JWT Editor Keys中新建对称密钥。如果版本提供Specify secret明文输入选项,直接填入已找到的 Secret,由插件完成编码。 - 如果直接编辑 JWK,注意
k字段填写的是密钥字节的 Base64URL 编码,不是明文 Secret,不要把两种输入方式混淆。 - 先使用候选密钥验证原始 Token 的签名,再到 Repeater 的
JSON Web Token标签页修改 Payload。 - 点击
Sign,选择对应密钥重新签名,保持靶场原本使用的 HS256 算法。 - 发送请求,结合响应正文、跳转位置和实际权限判断结果。
不能把“302 = 密钥错误,200 = 密钥正确”当作通用规则。 302 可能是正常跳转,200 也可能返回登录页或错误提示。密钥是否匹配原签名、请求是否通过身份认证、是否获得目标权限,是不同的判断。
当前官方 JWT Editor 支持 Attack → Weak HMAC secret。不同版本的菜单可能有差异,没有该功能时可以使用下方的 Hashcat 方法。参见 JWT Editor 官方说明。
2. Hashcat:离线字典测试
先把抓到的完整原始 JWT 保存为 jwt.txt,一行一个 Token。不要包含 Bearer 、Cookie 名称、引号或换行拆分;也不要先改 Payload,否则就不是在验证服务器原本生成的签名了。
下面的命令假设已经安装 Hashcat,并准备好 jwt.txt 和解压后的 rockyou.txt。文件不在当前目录时,需要填写实际路径;rockyou.txt 不会由命令自动下载。
命令一:使用字典测试候选密钥
hashcat -m 16500 -a 0 jwt.txt rockyou.txt
| 部分 | 含义 |
|---|---|
hashcat |
启动 Hashcat。 |
-m 16500 |
指定 JWT 模式;本文用于 HS256 签名的共享密钥测试,不是破解 RS256 私钥。 |
-a 0 |
使用直接字典模式,依次将字典中的条目作为候选密钥。 |
jwt.txt |
待验证的完整 JWT 文件,是测试目标,不是字典。 |
rockyou.txt |
候选密钥字典,通常每行一个候选值。可以换成自己准备的靶场字典。 |
执行时,Hashcat 用每个候选 Secret 对原 JWT 的前两段计算签名,再与第三段比较。这是本机离线计算,不是逐条向网站发送登录请求。参见 PortSwigger 的 JWT 弱密钥说明。
常见结果可以这样理解:
Recovered: 1/1 (100.00%):加载的一个目标已经找到匹配密钥;不代表网站管理员权限已经验证成功。Status: Cracked:目标已破解完成,可以查看恢复出的密钥。Status: Exhausted且Recovered: 0/1:当前候选已尝试完但没有匹配,不代表密钥一定安全。
命令二:查看已经找到的密钥
hashcat -m 16500 --show jwt.txt
-m 16500:仍按相同 JWT 模式识别输入。--show:把jwt.txt中的目标与 Hashcat 的结果缓存(potfile)比较,显示已经恢复出的结果,不会重新跑字典。jwt.txt:指定要查询哪些 Token 的结果,所以这里不再需要-a 0和rockyou.txt。
默认输出通常由“原 JWT”和“恢复出的密钥”组成,中间用冒号分隔。下面只是格式示意,dragon 不代表这次实际恢复出的值:
原JWT字符串:dragon
如果没有输出,先检查是否已经破解成功、是否使用同一份目标文件,以及两次运行是否使用同一个 potfile。此前禁用了缓存、清除了缓存或切换了运行环境,也可能查不到结果。缓存包含恢复出的密钥,不应提交到博客仓库。
参数含义可对照 Hashcat 官方文档。在 Windows PowerShell 中,如果程序位于当前目录且未加入 PATH,可将命令开头的 hashcat 换成 ./hashcat.exe。
三、完整的攻击链(Attack Chain)
- 截取凭证: 浏览器登录靶场,Burp 拦截包含 JWT 的请求。
- 破解密钥: 将原始 JWT 交给 Hashcat,或使用 JWT Editor 的弱 HMAC 密钥测试功能尝试字典。
- 篡改身份: 拿到明文密钥后,在 JWT Editor 中导入该密钥,将 Payload 里的
"role":"user"改为"role":"admin";字段以实际靶场的授权逻辑为准。 - 伪造签名: 点击
Sign,用找到的密钥重新计算签名,再发送请求验证权限变化。
四、复盘 Tips
- 弱密钥利用是用找到的密钥重新生成有效签名,与“服务器不验证签名”不同。 所以这次修改 Payload 后需要重新签名,不能照搬上一篇保留原签名的测试方式。
- 共享密钥字典测试针对 HS256 等 HMAC 算法,不能直接套到 RS256 私钥上。 本文的具体命令以 HS256 为例,其他算法需要确认工具和模式是否支持。