Loading ...
JWT 攻击方式

一、JWT 基础认知

1. 定义与结构

JSON Web Token(JWT)是一种基于 JSON 的轻量级身份验证令牌,用于在客户端与服务端之间安全传递声明信息,常见于单点登录(SSO)场景。

  • 结构组成:由 3 部分通过.拼接,分别为:

    • Header(头部):Base64 编码的 JSON,包含令牌类型(typ: "JWT")和签名算法(alg: "HS256"等)。

    • Payload(负载):Base64 编码的 JSON,存储用户 ID、权限、过期时间等核心数据(如{"user": "admin", "exp": 1620000000})。

    • Signature(签名):通过 Header 指定的算法,对Header.Base64 + "." + Payload.Base64与密钥计算得出的哈希值,用于验证令牌完整性。

二、核心攻击方式

1. 敏感信息泄露

原理

Header 和 Payload 采用可逆的 Base64URL 编码(非加密),任何人获取令牌后均可解码读取内容,若包含密码、密钥等敏感数据将直接泄露。

利用方法
  • 解码工具

    • Linux:echo "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" | base64 -d (输出:{"typ":"JWT","alg":"HS256"}

    • 浏览器控制台:atob("eyJ1c2VyIjoiYWRtaW4ifQ") (输出:{"user":"admin"}

    • Python:

      import base64
      print(base64.b64decode("eyJ1c2VyIjoiYWRtaW4ifQ".encode()).decode())
风险案例

某网站在 Payload 中包含用户明文密码,攻击者截获令牌后直接解码获取,进而登录用户账户。

2. 算法置空攻击(alg: none)

原理

JWT 协议支持将签名算法设为"none",此时签名字段为空(仅保留.),服务端若未禁用该配置,会跳过签名验证,直接信任令牌内容。

利用步骤
  1. 获取原始令牌 例如:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4ifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

  2. 修改 Header 算法为none 解码 Header 并改为{"alg": "none", "typ": "JWT"},重新 Base64 编码为:eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0

  3. 删除签名部分 最终伪造令牌:eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4ifQ.(末尾保留.

  4. 发送请求:若服务端接受该令牌并返回管理员权限页面,则漏洞存在。

防御建议

服务端配置中明确指定允许的签名算法(如仅支持HS256),禁止"none"算法。

3. 密钥混淆攻击(HS256 vs RS256)

原理
  • HS256:对称加密算法,使用同一密钥进行签名和验证。

  • RS256:非对称加密算法,使用私钥签名、公钥验证。 若服务端同时支持两种算法,攻击者可将algRS256改为HS256,诱使服务端用公钥作为 HS256 的密钥验证签名(公钥通常可公开获取)。

利用步骤
  1. 获取公钥:通过目标网站的/.well-known/jwks.json或证书文件提取公钥(如public.pem)。

  2. 构造恶意令牌

    • 修改 Header 的algHS256

    • 用获取的公钥作为密钥,对修改后的 Header 和 Payload 进行 HS256 签名。

  3. 发送请求:服务端若用公钥验证 HS256 签名,将认可伪造的令牌。

防御建议

服务端仅启用一种加密算法(如纯 RS256),并严格校验算法类型,拒绝非预期算法。

4. 无效签名绕过

原理

服务端未严格验证签名(如代码中省略签名校验步骤),攻击者可直接修改 Payload(如将user: "test"改为user: "admin"),无需重新签名即可通过验证。

利用案例

某网站 “个人资料页” 的访问控制依赖 JWT 中的user字段,攻击者截获令牌后:

  1. 解码 Payload 并修改user"admin",重新 Base64 编码。

  2. 保持原始签名不变(或随意修改),发送请求后成功访问管理员资料页。

5. 暴力破解密钥(针对 HMAC 算法)

原理

HS256/HS384 等对称算法的签名依赖密钥,若密钥强度低(如弱密码),可通过字典攻击离线破解。

利用工具与命令
  • jwt_tool(主流 JWT 测试工具):

    # 用字典1.txt暴力破解密钥
    python jwt_tool.py <目标令牌> -C -d 1.txt
    # 示例输出:[+] 密钥匹配:abc123
  • 破解成功后:用密钥伪造任意令牌(如将user改为admin,重新签名)。

6. 密钥泄露

原理

攻击者通过其他漏洞获取签名密钥(如 Git 信息泄露、目录遍历、XXE 等),直接伪造合法令牌。

常见泄露场景
  • 代码仓库泄露:.git目录中遗留jwt_secret.key文件。

  • 任意文件读取:通过../../etc/jwt/secret路径读取密钥。

  • XXE 漏洞:利用 XML 外部实体注入读取密钥文件。

7. KID 参数操纵

原理

kid(Key ID)是 Header 中的可选字段,用于指定验证密钥(如从文件系统或数据库中检索),若未过滤用户输入,可引发多种攻击。

具体利用
  • 目录遍历 构造"kid": "../../../etc/passwd",使服务端用系统文件/etc/passwd作为验证密钥,攻击者用该文件内容签名令牌。

  • SQL 注入 kid用于数据库查询(如SELECT key FROM keys WHERE id = '${kid}'),可注入: "kid": "1' UNION SELECT 'my_secret';--",使服务端用my_secret作为密钥。

  • 命令注入 kid传入文件读取函数(如 Ruby 的open()),可构造: "kid": "key.txt|whoami",执行系统命令并返回结果。

8. 头部参数操纵(JKU/JWK/X5U)

原理
  • JKU(JWK Set URL):指定包含验证密钥的 URL,服务端会自动下载并使用该 URL 中的密钥。

  • JWK(JSON Web Key):直接在 Header 中嵌入验证密钥。

  • X5U/X5C:指定包含公钥证书的 URL 或嵌入证书内容。

利用步骤
  1. 托管恶意密钥:攻击者在自己的服务器上放置恶意 JWK 文件(如https://attacker.com/jwks.json)。

  2. 构造令牌:Header 中设置"jku": "https://attacker.com/jwks.json"

  3. 发送请求:服务端下载并使用恶意密钥验证,认可伪造的令牌。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇