前言:本文依旧是个人对jwt一些初步的总结,网上很多写的都是如何进行爆破,用hashcat,bp的插件啥的,但是很少有讲环境该怎么搭建(当然了现在LLM的好处也正是这种地方),更多的是利用技巧,因此,本篇写的目的是自己对jwt基础的一些整理,以及如何搭建环境和最基础的对称加密的爆破,有一个更加深刻的印象.

一.前置知识

1.什么是jwt

JWT(JSON Web Token)是一种用于在网络应用中传输信息的开放标准(RFC 7519)。它通常被用于对用户进行身份验证和授权。JWT由三部分组成,每个部分之间使用点(.)进行分隔,这三部分分别是:

Header(头部): 包含了令牌的元数据和加密算法信息。
Payload(载荷): 存储了要传输的数据,如用户的身份信息和一些声明。Payload有三种类型:注册的声明(Reserved claims)、公共的声明(Public claims)和私有的声明(Private claims)。
Signature(签名): 使用头部指定的加密算法对头部和载荷进行签名,以确保令牌在传输过程中没有被篡改。


2.结构

1. Header(头部)

头部包含两部分信息:令牌类型(通常为 JWT)和签名算法(如 HMAC SHA256 或 RSA)。例如:

{
 "alg": "HS256",
 "typ": "JWT"
}

该部分会经过 Base64 编码,形成 JWT 的第一部分。

2. Payload(负载)

负载部分存储声明信息(Claims),包括用户的非敏感数据。声明分为三种类型:

  • 注册声明:如 iss(签发者)、exp(过期时间)、sub(主题)。

  • 公共声明:如用户 ID、角色等。

  • 私有声明:由提供者和消费者自定义的信息。

{
 "sub": "1234567890",
 "name": "John Doe",
 "admin": true,
 "exp": 1710000000
}

该部分也会经过 Base64 编码,形成 JWT 的第二部分.

3. Signature(签名)

签名用于验证令牌的完整性,防止数据被篡改。签名的生成方式如下:

HMACSHA256(
 base64UrlEncode(header) + "." + base64UrlEncode(payload),
 secret
)

HMACSHA256就像一个"带密钥的哈希函数",它确保只有知道密钥的人才能生成有效的签名,同时防止了各种密码学攻击,而这里的secret便是密钥.

3.工作原理

  • 用户登录后,服务器根据用户信息生成 JWT,并将其返回给客户端。

  • 客户端保存 JWT(通常存储在浏览器的 localStorage 或 sessionStorage 中)。

  • 每次请求时,客户端将 JWT 放入请求头中,例如:

Authorization: Bearer <token>

  • 服务器接收到请求后,解析 JWT,验证签名并检查是否过期,从而完成鉴权。

二.环境搭建

这里选用的是Kali,主机上装一堆东西容易污染主机环境.[这里还是说一下吧,linux里面复制粘贴是ctrl+shift+c或者加v)

最开始还是先更新一下:

sudo apt update

依旧是git发力:

sudo git clone https://github.com/ticarpi/jwt_tool.git

这里有一个问题是我因为一直用的是kali而不是root,而直接用kali切换到jwt_tool目录下权限不够,所以要让普通用户也有这个权限:

sudo chown -R kali:kali jwt_tool


chown:(change owner) Linux 中用于修改文件/目录所有权的命令。
-R:(recursive) 递归参数。意味着不仅修改 jwt_tool 文件夹本身,还会将其包含的所有子目录和文件一并修改。
kali:kali:指定新的“拥有者”和“所属群组”。冒号前的是用户名(kali),冒号后的是组名(kali)。

即以系统管理员权限,递归地将 jwt_tool 文件夹及其内部所有文件和子目录的拥有者和所属群组都修改为 kali 用户

然后因为这里为了方便是直接安装所有依赖,如果是虚拟环境的话要自己建立一个下次使用还要重新启动对我这种小辣鸡还是太难了:

sudo apt install python3-requests python3-colorama python3-termcolor python3-ratelimit python3-jwt

然后我们再进到jwt tool所在的文件地址:

cd jwt_tool

然后我们再进行验证一下:

python3 jwt_tool.py --help

如果正常的话界面就是这样的:

然后这里我直接用的是rockyou字典,但是首先需要先解压一下,完整过程如下:

# 检查rockyou是否存在
ls -la /usr/share/wordlists/

# 如果看到rockyou.txt.gz,解压它
sudo gunzip /usr/share/wordlists/rockyou.txt.gz

# 确认解压成功
ls -la /usr/share/wordlists/rockyou.txt

那么接下来就能开始我们的爆破了.

三.爆破流程

这里先给出要爆破的jwt:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTc3MTk5NjQ0MSwiZXhwIjoxNzcyMDAzNjQxLCJuYmYiOjE3NzE5OTY0NDEsInN1YiI6InVzZXIiLCJqdGkiOiI2MGM2M2RmMjdmOTFiZDg5MjU3ODc1OTA2ZjBhZWNiNCJ9.-0Wyh-_OgzWt5ub-sP6XNtXxwEoeYudMD1wzcFNYBEI

我们可以放到jwt.io里面看一下是什么算法:

或者也可以直接kali里面跑:

python3 jwt_tool.py "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTc3MTk5NjQ0MSwiZXhwIjoxNzcyMDAzNjQxLCJuYmYiOjE3NzE5OTY0NDEsInN1YiI6InVzZXIiLCJqdGkiOiI2MGM2M2RmMjdmOTFiZDg5MjU3ODc1OTA2ZjBhZWNiNCJ9.-0Wyh-_OgzWt5ub-sP6XNtXxwEoeYudMD1wzcFNYBEI"

可以看到为HS256对称加密算法,该过程如下:

准备数据:

Header:指定算法(“alg”: “HS256”)和类型(“typ”: “JWT”)。
Payload:存储实际数据(如用户信息、过期时间 exp)。
Secret Key:用于签名(仅签名方持有)。
Base64Url 编码 Header 和 Payload:

将 Header 和 Payload 分别进行 Base64Url 编码,得到 encodedHeader 和 encodedPayload。
计算签名:

拼接字符串:signingInput = encodedHeader + “.” + encodedPayload。
使用 HMAC-SHA256 算法,对 signingInput 和 Secret Key 计算签名:signature = HMAC-SHA256(signingInput, SecretKey)。
将签名进行 Base64Url 编码,得到 encodedSignature。
组合成 JWT:

jwt = encodedHeader + “.” + encodedPayload + “.” + encodedSignature

接下来就是我们的爆破了,输入如下命令:

python3 jwt_tool.py "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTc3MTkzOTk2MiwiZXhwIjoxNzcxOTQ3MTYyLCJuYmYiOjE3NzE5Mzk5NjIsInN1YiI6InVzZXIiLCJqdGkiOiIxNTNjM2RiMzRlOTNkYWQxYTI0NGQwNzAyYWU5NTBlZCJ9.gnMf8m_VRcwqAmtYAcoGvEHzZ6CZjNqeoKnRsETGFBo" -C -d /usr/share/wordlists/rockyou.txt -v

得到结果为123456:

那么这个爆破是怎么爆出来的呢?因为这个WT使用的是对称加密算法 HS256,这意味着:

  • 加密和解密使用同一个密钥

  • 签名是使用密钥对Header和Payload进行哈希计算的结果

  • 如果能找到一个密钥,使得用这个密钥重新计算出的签名与原始签名完全一致,那么这个密钥就是正确的

# 伪代码示例
header = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
payload = "eyJpc3MiOiJhZG1pbiIsImlhdCI6MTc3MTkzOTk2MiwiZXhwIjoxNzcxOTQ3MTYyLCJuYmYiOjE3NzE5Mzk5NjIsInN1YiI6InVzZXIiLCJqdGkiOiIxNTNjM2RiMzRlOTNkYWQxYTI0NGQwNzAyYWU5NTBlZCJ9"
original_signature = "gnMf8m_VRcwqAmtYAcoGvEHzZ6CZjNqeoKnRsETGFBo"

# 从字典中读取每个可能的密钥
with open("rockyou.txt", "r") as f:
    for key in f:
        key = key.strip()
        # 使用当前密钥计算签名
        calculated_signature = HMACSHA256(f"{header}.{payload}", key)
        # 比较计算出的签名是否与原始签名匹配
        if calculated_signature == original_signature:
            print(f"找到密钥: {key}")
            break

四.常用参数

参数 完整写法 功能说明 使用示例 备注
🔧 基础参数
-h --help 显示帮助信息 python3 jwt_tool.py -h 查看所有可用参数
-v --verbose 详细输出模式 -v 显示每个尝试的密钥
-q --quiet 安静模式 -q 只显示最终结果
-t --threads 设置线程数 -t 20 加速爆破,默认5线程
🔨 爆破相关
-C --crack 启动爆破模式 -C -d rockyou.txt 尝试找出密钥
-d --dict 指定字典文件 -d /path/to/dict.txt 每行一个密钥
-k --key 指定密钥验证 -k "secret123" 用已知密钥验证
-o --output 保存结果到文件 -o found.txt 输出找到的密钥
🔄 攻击模式
-X --exploit 漏洞利用模式 -X a a=混淆攻击
-X n n=none算法攻击
-X k k=密钥混淆
-I --inject 注入恶意Payload -I -p "admin" 修改payload内容
-R --regex 正则表达式搜索 -R "admin" 在JWT中搜索
📝 格式相关
-b --bearer 处理Bearer token -b "Bearer JWT" 自动去除Bearer前缀
-c --cookie 处理Cookie格式 -c "session=JWT" 从Cookie提取JWT
-H --header 添加HTTP头 -H "User-Agent: Mozilla" 请求时使用
🌐 网络相关
-u --url 指定目标URL -u https://example.com 发送JWT到目标
-m --method HTTP方法 -m POST GET/POST等
-p --proxy 使用代理 -p http://127.0.0.1:8080 配合Burp使用
-d --data POST数据 -d "user=admin" 发送POST请求
🔬 分析参数
-D --decode 解码JWT -D 只解码不验证
-V --verify 验证签名 -V -k "key" 验证JWT有效性
-S --show 显示JWT信息 -S 显示header/payload
-T --timer 计时攻击测试 -T 测试响应时间
🎯 常用组合
基础爆破 -C -d rockyou.txt -v 爆破+详细输出 新手推荐
快速爆破 -C -d rockyou.txt -t 20 多线程加速 效率最高
漏洞测试 -X a -X n -X k 多种攻击测试 全面检测
完整测试 -C -d rockyou.txt -t 20 -v -o result.txt 爆破+保存+详细 专业模式

 实战场景示例

场景 推荐命令 说明
首次使用 python3 jwt_tool.py "JWT" 先看看JWT基本信息
爆破HS256 python3 jwt_tool.py "JWT" -C -d rockyou.txt -t 20 -v 标准爆破流程
测试none漏洞 python3 jwt_tool.py "JWT" -X n 检查能否绕过
算法混淆 python3 jwt_tool.py "JWT" -X a RS256→HS256攻击
修改payload python3 jwt_tool.py "JWT" -I -p '{"user":"admin"}' 伪造身份
网络测试 python3 jwt_tool.py -u https://target.com -H "Auth: JWT" 发送到目标
配合Burp python3 jwt_tool.py "JWT" -C -d dict.txt -p http://127.0.0.1:8080 拦截查看请求
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐