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:远程获取公钥信息的URL
  • cty:内容类型(可能用于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

适用场景:服务器不验证签名

  1. 解码JWT
  2. 修改sub字段为特权用户(如administrator)
  3. 重新编码发送

2.2 算法设置为none

步骤

  1. 修改header中的alg为"none"
  2. 删除Signature部分(保留最后的点)
  3. 发送修改后的Token

2.3 弱密钥爆破

步骤

  1. 使用hashcat爆破弱密钥:
    hashcat -a 0 -m 16500 JWT_Token ./jwt.secrets.list
    
  2. 获取密钥后(如"secret1"),在Burp中:
    • 添加新对称密钥(New symmetric Key)
    • k替换为密钥的base64编码
  3. 修改payload后使用该密钥重新签名

2.4 JWK标头注入

适用场景:服务器使用嵌入的公钥验证签名

  1. 生成RSA密钥对
  2. 在Request中选择"Embedded JWK"攻击
  3. 系统会自动嵌入公钥并签名
  4. 发送修改后的Token

2.5 利用JKU获取公钥

适用场景:服务器使用JKU远程获取公钥

  1. 生成RSA密钥对
  2. 复制JWK格式的公钥,添加keys头:
    {
      "keys": [
        {公钥内容}
      ]
    }
    
  3. 将公钥映射到可访问的URL
  4. 修改JWT:
    • 设置kid为公钥的kid
    • 设置jku为公钥URL
    • 修改sub为特权用户
  5. 使用私钥签名后发送

2.6 Header路径遍历

利用Linux的/dev/null文件

  1. 生成对称密钥,设置k为空字节(base64为"AA==")
  2. 修改:
    • sub为特权用户
    • kid为目录遍历到null文件(如"../../../../dev/null")
  3. 使用生成的密钥签名

2.7 算法混淆攻击

适用场景:服务器本应使用RSA但实现有缺陷

  1. 获取服务器公钥(如/jwks.json)
  2. 取出RSA公钥内容,新建RSA密钥
  3. 使用PEM格式公钥的base64作为k生成对称密钥
  4. 修改:
    • alg为HS256
    • sub为特权用户
  5. 使用对称密钥签名

2.8 kid参数注入

潜在风险

  • 命令注入(如Ruby的open函数)
  • 目录遍历
  • SQL注入

3. 防御建议

  1. 使用最新的JWT库:虽然稳定性可能受影响,但安全性更高
  2. 严格白名单控制
    • jku标头设置严格白名单
    • 限制可接受的算法类型(禁用"none")
  3. kid参数防护
    • 防止目录遍历
    • 防止命令/SQL注入
  4. 令牌管理
    • 设置合理的过期时间(exp)
    • 实现令牌撤销机制
  5. 其他安全措施
    • 避免通过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实现的安全性,而开发人员则可以使用这些知识来加固自己的系统。

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 :远程获取公钥信息的URL cty :内容类型(可能用于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爆破弱密钥: 获取密钥后(如"secret1"),在Burp中: 添加新对称密钥(New symmetric Key) 将 k 替换为密钥的base64编码 修改payload后使用该密钥重新签名 2.4 JWK标头注入 适用场景 :服务器使用嵌入的公钥验证签名 生成RSA密钥对 在Request中选择"Embedded JWK"攻击 系统会自动嵌入公钥并签名 发送修改后的Token 2.5 利用JKU获取公钥 适用场景 :服务器使用JKU远程获取公钥 生成RSA密钥对 复制JWK格式的公钥,添加 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 为HS256 sub 为特权用户 使用对称密钥签名 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 用于爆破弱密钥: 通过掌握这些技术,安全测试人员可以全面评估JWT实现的安全性,而开发人员则可以使用这些知识来加固自己的系统。