文章目录
-
- 前言
- 一、JWT基础与识别
-
- [1. 什么是JWT](#1. 什么是JWT)
- [2. JWT识别特征](#2. JWT识别特征)
- [3. JWT在线解析工具](#3. JWT在线解析工具)
- 二、JWT安全测试"三件套"
- 三、弱密钥爆破
-
- [1. 原理](#1. 原理)
- [2. 测试方法](#2. 测试方法)
- [3. 密钥泄露点审计](#3. 密钥泄露点审计)
- 四、算法篡改攻击
-
- [1. None算法攻击](#1. None算法攻击)
- [2. RS256转HS256算法切换攻击](#2. RS256转HS256算法切换攻击)
- [3. 算法混淆攻击](#3. 算法混淆攻击)
- 五、签名绕过与验签缺失
-
- [1. 直接修改Payload保留原签名](#1. 直接修改Payload保留原签名)
- [2. 截断Token测试](#2. 截断Token测试)
- [3. 空签名测试](#3. 空签名测试)
- 六、KID注入攻击
-
- [1. KID字段简介](#1. KID字段简介)
- [2. SQL注入](#2. SQL注入)
- [3. 命令注入](#3. 命令注入)
- [4. 文件读取](#4. 文件读取)
- 七、Token替换与响应篡改
-
- [1. 响应包Token替换](#1. 响应包Token替换)
- [2. Match and Replace自动化篡改](#2. Match and Replace自动化篡改)
- [3. Payload字段篡改重点](#3. Payload字段篡改重点)
- 八、嵌套加密处理
-
- [1. 识别嵌套加密](#1. 识别嵌套加密)
- [2. 完整伪造链条](#2. 完整伪造链条)
- 九、JWT与其他漏洞的组合利用
-
- [1. JWT + 信息泄露](#1. JWT + 信息泄露)
- [2. JWT + 前端鉴权绕过](#2. JWT + 前端鉴权绕过)
- [3. JWT + OAuth劫持](#3. JWT + OAuth劫持)
- 十、实战心得
-
- [1. 遇到JWT必测三件套](#1. 遇到JWT必测三件套)
- [2. 框架默认密钥是高危点](#2. 框架默认密钥是高危点)
- [3. 密钥来源多元化](#3. 密钥来源多元化)
- [4. 前端源码辅助权限推测](#4. 前端源码辅助权限推测)
- [5. 嵌套加密需要完整还原](#5. 嵌套加密需要完整还原)
- [6. 测试高权限接口验证真实权限](#6. 测试高权限接口验证真实权限)
- [7. 多种算法尝试](#7. 多种算法尝试)
- 十一、结语
⚠️本博文所涉安全渗透测试技术、方法及案例,仅用于网络安全技术研究与合规性交流,旨在提升读者的安全防护意识与技术能力。任何个人或组织在使用相关内容前,必须获得目标网络 / 系统所有者的明确且书面授权,严禁用于未经授权的网络探测、漏洞利用、数据获取等非法行为。
前言
JSON Web Token(JWT)是现代Web应用中广泛使用的身份认证机制。它通过将用户信息编码在Token中,实现了无状态的身份验证。然而,JWT的实现方式多种多样,许多开发者在密钥管理、算法选择和签名验证等环节存在安全疏忽,导致JWT成为SRC漏洞挖掘中的高频突破口。本文将系统性地介绍JWT的安全测试方法论,帮助读者建立完整的JWT渗透测试思维体系。
一、JWT基础与识别
1. 什么是JWT
JWT由三部分组成,通过点号(.)分隔:
Header.Payload.Signature
Header :声明签名算法和Token类型
Payload :包含用户身份信息和声明
Signature:对Header和Payload的签名
2. JWT识别特征
快速识别方法:
- JWT Token以
eyJ开头(Base64编码的{") - 包含两个点号分隔的三段结构
- 常见于
Authorization: Bearer请求头中
常见存放位置:
- HTTP请求头:
Authorization: Bearer <token> - Cookie:
token=<jwt> - 响应体:
{"token": "<jwt>", "accessToken": "<jwt>"} - URL参数:
?token=<jwt>
3. JWT在线解析工具
- jwt.io:最权威的JWT在线解析和调试平台,支持手动修改Header和Payload
- 其他在线解码工具:Base64解码后查看明文结构
二、JWT安全测试"三件套"
在SRC漏洞挖掘中,遇到JWT身份凭证时,建议按照以下顺序进行系统化测试:
| 测试顺序 | 测试类型 | 核心方法 | 成功率 |
|---|---|---|---|
| 第一步 | 弱密钥爆破 | 使用工具爆破签名密钥 | 中高 |
| 第二步 | 算法篡改 | 将alg改为none或切换算法 |
中 |
| 第三步 | 验签缺失 | 修改Payload后保留原签名 | 低但危害大 |
核心理念:由易到难逐步验证,先爆破、再改算法、最后测试不验签。
三、弱密钥爆破
1. 原理
JWT使用对称密钥(HMAC算法)或非对称密钥(RSA/ECDSA算法)进行签名。当使用HMAC算法(HS256/HS384/HS512)时,如果密钥强度不足(短密钥、常见单词、默认密钥),攻击者可以通过爆破获取密钥,进而伪造任意Token。
2. 测试方法
步骤1:识别算法
- 将JWT复制到jwt.io解析
- 查看Header中的
alg字段 - 如果为
HS256、HS384、HS512,则存在弱密钥爆破的可能
步骤2:选择工具
- TscanPlus:内置JWT弱密钥爆破功能,"轻武器"模块可快速检测
- hashcat:高性能密码爆破工具,支持JWT格式
- jwt_tool:专门的JWT安全测试工具
- c-jwt-cracker:C语言编写的高速JWT爆破工具
步骤3:执行爆破
- 使用常见密钥字典(top1000、top10000)
- 针对目标特征构造定制化字典(公司名称、产品名、域名变体)
- 关注框架默认密钥(如
secret、your-256-bit-secret、jwt-secret)
步骤4:验证利用
- 获取密钥后,在jwt.io中修改Payload中的身份字段
- 使用密钥重新签名
- 替换原Token测试是否生效
3. 密钥泄露点审计
除了爆破,还应主动寻找密钥泄露:
代码仓库搜索:
- GitHub/Gitee搜索目标项目源码
- 重点检查
example.env、README、config文件中的默认硬编码密钥 - 搜索关键词:
JWT_SECRET、SECRET_KEY、jwt.key、token_key
前端源码审计:
- 反编译小程序/APK后搜索密钥相关字符串
- 分析前端JS Bundle中的配置信息
配置文件泄露:
- 通过信息收集发现的配置文件中可能包含JWT密钥
- 如
application.yml、config.js、.env等
四、算法篡改攻击
1. None算法攻击
原理 :将JWT Header中的alg字段改为none,表示不使用签名算法。如果服务端未正确校验算法类型,将接受无签名的Token。
测试步骤:
- 解码原JWT的Header和Payload
- 将Header中的
alg改为none - 修改Payload中的身份字段(如
user_id、role) - 重新Base64编码Header和Payload
- 移除Signature部分(None算法不需要签名)
- 组合为新的Token:
新Header.新Payload.(注意末尾的点号)
自动化脚本 :
可使用Python的PyJWT库构造None算法攻击Token,设置algorithm=None和key=None即可生成无签名Token。
注意事项:
- 部分服务端会过滤
none(大小写敏感),可尝试None、nOne、NONE - 某些JWT库的实现会拒绝
none算法,但自定义实现可能存在漏洞
2. RS256转HS256算法切换攻击
原理:当服务端使用RS256(RSA非对称算法)时,理论上应该使用私钥签名、公钥验证。但如果服务端在验证时未严格校验算法类型,攻击者可以将算法改为HS256(HMAC对称算法),并使用服务端公开的公钥作为HS256的对称密钥进行签名。
攻击条件:
- 服务端使用RS256/ES256等非对称算法
- 攻击者能够获取服务端的公钥(通常可从证书、JWKS端点获取)
- 服务端验证时未固定算法类型
测试步骤:
- 获取服务端的公钥(从证书、
.well-known/jwks.json、源码中提取) - 将JWT Header中的
alg从RS256改为HS256 - 修改Payload中的身份字段
- 使用公钥作为HS256的对称密钥进行HMAC签名
- 发送伪造的Token测试服务端是否接受
3. 算法混淆攻击
测试思路:
- 尝试将
alg改为其他算法(如HS384、HS512) - 如果服务端使用多算法支持库,可能存在算法混淆漏洞
- 观察服务端对不同算法的响应差异
五、签名绕过与验签缺失
1. 直接修改Payload保留原签名
测试方法:
- 解码JWT的Payload部分
- 修改身份字段(如
user_id、role、isAdmin) - 重新Base64编码Payload
- 保留原Signature不变
- 组合为:
原Header.新Payload.原Signature
成功条件:服务端未验证签名,或验证逻辑存在缺陷。
2. 截断Token测试
测试方法:
- 移除Signature部分,只发送
Header.Payload. - 观察服务端是否接受不完整的Token
3. 空签名测试
测试方法:
- 将Signature部分替换为空字符串或随机字符串
- 观察服务端的验证行为
六、KID注入攻击
1. KID字段简介
KID(Key ID)是JWT Header中的一个可选字段,用于指定服务端应该使用哪个密钥进行验证。如果服务端根据KID值动态加载密钥,且未对KID值进行严格校验,可能存在注入漏洞。
2. SQL注入
原理:如果服务端将KID值直接拼接到SQL查询中,攻击者可以通过KID字段注入恶意SQL。
测试Payload:
xxx_key' UNION SELECT 'mykey' FROM INFORMATION_SCHEMA.SYSTEM_USERS --
关键点:
xxx_key必须是不存在于数据库中的Key ID- 通过UNION SELECT注入自定义密钥
- 注入的密钥可以是任意字符串,也可进行Base64编码
测试方法:
- 分析正常JWT的KID值格式
- 构造带有SQL注入Payload的KID值
- 结合时间盲注或布尔盲注确认注入点
3. 命令注入
原理:如果服务端使用KID值执行系统命令(如通过脚本读取密钥文件),可能存在命令注入。
测试方法:
- 在KID值中拼接系统命令(如
| whoami) - 观察服务端响应是否存在命令执行痕迹
- 某些语言(如Ruby)通过
open函数读取文件时,可能执行管道命令
4. 文件读取
原理:如果服务端根据KID值读取本地文件作为密钥,攻击者可以通过路径遍历读取任意文件。
测试方法:
- 将KID值设为文件路径(如
/etc/passwd) - 使用路径遍历(如
../../../../../etc/passwd) - 指向
/dev/null获取空密钥,配合None算法攻击
七、Token替换与响应篡改
1. 响应包Token替换
测试方法:
- 使用正常账号登录,抓包获取JWT
- 在jwt.io中使用爆破出的密钥或发现的密钥伪造高权限Token
- 拦截登录响应包
- 将响应中的Token替换为伪造的高权限Token
- 观察前端是否以高权限身份加载界面和功能
关键观察:
- 前端根据Token中的角色字段渲染界面
- 后端API是否真正校验权限(前端显示管理员界面不代表后端允许操作)
- 需要进一步测试高权限接口是否可实际调用
2. Match and Replace自动化篡改
工具使用:
- 使用BurpSuite的Match and Replace功能
- 配置规则自动替换响应中的Token字段
- 实现自动化的权限切换测试
3. Payload字段篡改重点
常见可篡改字段:
user_id、uid、sub:用户身份标识role、roles、authority:角色权限isAdmin、admin:管理员标志username、email:用户名/邮箱exp、iat:过期时间/签发时间(尝试延长有效期)
前端源码辅助:
- 通过分析前端源码中的条件渲染逻辑(如
ng-if="role != 'admin'") - 推测系统中存在的高权限角色名称
- 为Token篡改提供目标角色值
八、嵌套加密处理
1. 识别嵌套加密
特征:JWT的Payload中包含额外加密的字段,如:
json
{
"user_id": 123,
"info": "AES加密后的Base64字符串"
}
2. 完整伪造链条
处理步骤:
- 获取JWT签名密钥(爆破或泄露)
- 分析嵌套加密字段的加密算法(AES、DES等)
- 从源码中提取嵌套加密的密钥和IV
- 解密嵌套字段,修改身份信息
- 重新加密嵌套字段
- 重新签名JWT
关键原则:JWT的伪造不只是修改Payload,当存在嵌套加密时,需要完整还原整个加解密链。
九、JWT与其他漏洞的组合利用
1. JWT + 信息泄露
攻击链:
信息泄露(源码/配置文件)→ 获取JWT密钥 → 伪造Token → 权限提升
2. JWT + 前端鉴权绕过
攻击链:
伪造高权限JWT → 替换响应包中的Token → 前端渲染管理员界面 → 调用高权限API
3. JWT + OAuth劫持
测试思路:
- 不要只测试主站,隐藏SSO/子站的JWT配置可能更弱
- 对主站和子站分别测试JWT的安全性
- 通过跨平台跳转行为发现非暴露的认证入口
十、实战心得
1. 遇到JWT必测三件套
弱密钥爆破 → 算法篡改 → 验签缺失,由易到难逐步验证。不要只测试一种就放弃。
2. 框架默认密钥是高危点
许多框架(如ThinkPHP、Spring Boot等)的示例配置中使用了默认JWT密钥,开发者未修改直接上线。通过框架识别可以快速定位可能的默认密钥。
3. 密钥来源多元化
除了爆破,还应主动从代码仓库、前端源码、配置文件、API文档中寻找密钥泄露。
4. 前端源码辅助权限推测
通过分析前端源码中的条件渲染逻辑,可以推测系统中存在的高权限角色名称,为Token篡改提供精确目标。
5. 嵌套加密需要完整还原
当JWT Payload中存在额外加密字段时,单纯修改JWT签名无法完成攻击,需要完整还原嵌套加密的密钥和算法。
6. 测试高权限接口验证真实权限
前端显示管理员界面不代表后端允许操作,必须实际调用高权限API验证权限是否真正提升。
7. 多种算法尝试
none、None、nOne、NONE都要尝试,不同JWT库对大小写的处理可能不同。RS256转HS256时,公钥的格式(PEM/DER/JWKS)需要正确转换。
十一、结语
JWT安全测试是SRC漏洞挖掘中的一个重要方向。从弱密钥爆破到算法篡改,从签名绕过到KID注入,每一种测试方法都可能发现高危漏洞。本文系统性地介绍了JWT的识别方法、安全测试"三件套"、弱密钥爆破、算法篡改、签名绕过、KID注入和Token替换的完整方法论,希望能帮助读者建立系统化的JWT渗透测试思维体系。
核心要点回顾
1. JWT识别:
- 以
eyJ开头的三段结构 - 常见于Authorization头、Cookie、响应体中
2. 安全测试三件套:
- 弱密钥爆破(优先级最高)
- 算法篡改(None攻击、RS256转HS256)
- 验签缺失测试
3. 密钥获取途径:
- 爆破(使用专业工具+定制化字典)
- 代码仓库搜索(GitHub/Gitee)
- 前端源码审计(反编译小程序/APK)
- 配置文件泄露
4. KID注入:
- SQL注入:通过UNION SELECT注入自定义密钥
- 命令注入:通过管道符号执行系统命令
- 文件读取:通过路径遍历读取任意文件
5. 组合利用:
- JWT + 信息泄露 → 快速获取密钥
- JWT + 前端鉴权绕过 → 权限提升
防御建议
对于防守方来说,JWT的安全防护需要从多个层面入手:
- 强密钥策略:使用足够长度的随机密钥(至少256位),禁止使用默认密钥
- 算法固定 :服务端验证时固定允许的算法类型,拒绝
none算法 - 严格验签:每个请求都必须验证JWT签名,不依赖前端传入的算法声明
- KID校验:对KID值进行严格的白名单校验,禁止路径遍历和特殊字符
- 密钥轮换:定期轮换JWT签名密钥
- 最小权限:Token中只包含必要的身份字段,不存储敏感权限信息
- 过期控制:设置合理的Token过期时间,配合刷新Token机制