JWT的认证bypass
字数 1688 2025-08-11 17:40:15
JWT认证绕过技术详解
1. JWT基础概念
1.1 JWT结构
JWT(JSON Web Token)由三部分组成,用点(.)分隔:
- Header:包含元数据,如算法类型
- Payload:包含实际数据(claims)
- Signature:用于验证令牌完整性
1.2 Header部分关键字段
alg:指定加密算法(如HS256或RS256)typ:令牌类型,通常为"JWT"kid:公钥ID标记jwk:包含附带的RSA密钥信息jku:远程获取公钥信息的URLcty:内容类型(可能用于XXE和反序列化攻击)
1.3 Payload部分关键字段
sub:认证的用户exp:过期时间(时间戳)iss:JWT签发者nbf:不早于时间(时间戳)domain:面向的用户jti:Token唯一标识符
1.4 常见签名算法
- RS256:采用SHA-256的RSA签名(非对称)
- HS256:带有SHA-256的HMAC(对称算法)
- none:无签名(不安全)
2. JWT绕过技术
2.1 直接修改Payload
适用场景:服务器不验证签名
- 解码JWT
- 修改
sub字段为特权用户(如administrator) - 重新编码发送
2.2 算法设置为none
步骤:
- 修改header中的
alg为"none" - 删除Signature部分(保留最后的点)
- 发送修改后的Token
2.3 弱密钥爆破
步骤:
- 使用hashcat爆破弱密钥:
hashcat -a 0 -m 16500 JWT_Token ./jwt.secrets.list - 获取密钥后(如"secret1"),在Burp中:
- 添加新对称密钥(New symmetric Key)
- 将
k替换为密钥的base64编码
- 修改payload后使用该密钥重新签名
2.4 JWK标头注入
适用场景:服务器使用嵌入的公钥验证签名
- 生成RSA密钥对
- 在Request中选择"Embedded JWK"攻击
- 系统会自动嵌入公钥并签名
- 发送修改后的Token
2.5 利用JKU获取公钥
适用场景:服务器使用JKU远程获取公钥
- 生成RSA密钥对
- 复制JWK格式的公钥,添加
keys头:{ "keys": [ {公钥内容} ] } - 将公钥映射到可访问的URL
- 修改JWT:
- 设置
kid为公钥的kid - 设置
jku为公钥URL - 修改
sub为特权用户
- 设置
- 使用私钥签名后发送
2.6 Header路径遍历
利用Linux的/dev/null文件:
- 生成对称密钥,设置
k为空字节(base64为"AA==") - 修改:
sub为特权用户kid为目录遍历到null文件(如"../../../../dev/null")
- 使用生成的密钥签名
2.7 算法混淆攻击
适用场景:服务器本应使用RSA但实现有缺陷
- 获取服务器公钥(如/jwks.json)
- 取出RSA公钥内容,新建RSA密钥
- 使用PEM格式公钥的base64作为
k生成对称密钥 - 修改:
alg为HS256sub为特权用户
- 使用对称密钥签名
2.8 kid参数注入
潜在风险:
- 命令注入(如Ruby的open函数)
- 目录遍历
- SQL注入
3. 防御建议
- 使用最新的JWT库:虽然稳定性可能受影响,但安全性更高
- 严格白名单控制:
- 对
jku标头设置严格白名单 - 限制可接受的算法类型(禁用"none")
- 对
- kid参数防护:
- 防止目录遍历
- 防止命令/SQL注入
- 令牌管理:
- 设置合理的过期时间(
exp) - 实现令牌撤销机制
- 设置合理的过期时间(
- 其他安全措施:
- 避免通过URL参数发送令牌
- 使用
aud声明指定预期接收者 - 使用强密钥并定期更换
- 验证所有签名
4. 工具使用
4.1 Burp Suite插件
- JWT Editor Keys:识别和编辑JWT
- 功能:
- 自动标记含JWT的请求
- 提供可视化编辑界面
- 支持密钥管理和签名
4.2 在线工具
- jwt.io:用于解码、验证和生成JWT
4.3 Hashcat
用于爆破弱密钥:
hashcat -a 0 -m 16500 JWT_Token ./jwt.secrets.list
通过掌握这些技术,安全测试人员可以全面评估JWT实现的安全性,而开发人员则可以使用这些知识来加固自己的系统。