JWT 相关漏洞再学习

简介

  • 介绍: 全名Json Web Token, 遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份
  • 结构: Header.Payload.Signature(每个段落单独用base64url加密)
    : 即使alg为"none", 即没有签名(jwt允许无签名), 结尾也需要点号
  • Header:
    作用: 一般由algtyp两个字段组成, 也有可选字段kid
    alg: 指定token加密使用的算法
    typ: 指定令牌的类型, 值基本为JWT
    kid: 指定使用的加密算法的密钥 在服务端的位置
  • Payload:
    作用: 储存着用户数据以及一些元数据有关的声明, 声明有三种(注册声明 公共声明 私有声明)
    注册声明: 由JWT系统自身预定义的声明

    • iss (Issuer): 令牌的发行者
    • sub (Subject): 令牌的主题
    • aud (Audience): 令牌的接收者
    • exp (Expiration Time): 过期时间
    • nbf (Not Before): 在此之前不可用
    • iat (Issued At): 发行时间
    • jti (JWT ID): 唯一标识符
      公共声明: 由使用JWT的人自由定义, 用于传递 非敏感信息
      私有声明: 由使用JWT的人自由定义, 用于传递 敏感信息
  • Signature:
    作用: 用于保护token完整性, 验证消息在传输过程中没有被更改,

    • : 并且对于使用私钥签名的token,它还可以验证JWT的发送方
      生成方法: 将header和payload两部分base64urlEncode后联结起来, 再用header指定的算法, 计算出签名
    • 即如HMAC-SHA256(base64urlEncode(header) + '.' + base64urlEncode(payload), secret_key)
  • 服务端:
    储存: 验证签名的密钥 (对于对称加密,这是一个密钥;对于非对称加密,这是一个私钥和公钥对)
    : JWT本身并不提供相关任何信息的存储, 而交给服务端自己进行逻辑操作与存储
  • 使用:
    1. 服务端根据登陆状态 将用户信息加密到token中,返给客户端
    2. 客户端收到服务端返回的token, 存储在cookie中, 并且每次通信都带上token. 服务端解密toke, 验证内容,完成相应逻辑
      • JWT的最佳用途是一次性授权Token, 用于给用户的操作进行标识, 而非给用户的状态进行标识
  • 与session的区别:
    内容: session会话返回的cookie只用于标识, 本身并没有任何含义; 而JWT包含了用户的相关信息
    管理方法: JWT理论上应用于无状态的请求; 而Session由于主要信息储存在客户端, 可用于有状态的请求
    跨平台: JWT比较容易跨平台; 而Session基本不能跨平台(得相关平台服务器会话数据互通才可)
  • 常见算法
    HS(HMAC-SHA): 对称加密, 有HS256 HS384 HS512
    RS(RSA-SHA): 非对称加密, RS256 RS384 RS512
    ES(ECDSA-SHA): 非对称加密, 有ES256 RS384 ES512
    PS(RSA-PSS-SHA256): 非对称加密, 有PS256 PS384 PS512

-- 通用漏洞 --

普通

  • 信息泄露: jwt中可能包含敏感信息, 解码后查看
    解码: https://jwt.io/ 或 手动base64url解码
  • 未对签名进行验证: 可任意修改Payload和Header中的值(因为不会校验签名)

空加密 -- 未对加密算法进行强验证

  • 前提: 生产环境中开启空加密算法, 且不检验alg/使用alg字段来决定算法
  • 使用: 将alg字段值改为"none"(可大小写绕过), 删除签名(点号仍需保留)

爆破密钥

  • 前提: 使用对称加密(HS256 HS384 HS512)
  • 爆破工具: hashcat jwtcrack john
  • hashcat(字典爆破): hashcat -a 0 -m 16500 <token> <wordlist>
  • jwt-cracker:
    暴力破解: jwt-cracker -t <token> -a [alphabet] --max [max_len]
    字典爆破: jwt-cracker -t <token> -d <wordlist>
    下载: npm install --global jwt-cracker
    注: 暴力破解五位以上的密钥将会特别慢
  • 爆破后: 爆破后使用对应密钥伪造签名(密钥要进行base64url加密后伪造)

修改加密算法 (非对称加密改为HMAC)

  • 前提: 知道非对称加密公钥, 且不检验alg/使用alg字段来决定算法
  • 原理:对于非对称加密, 私钥用于加密, 公钥用于验证, 若改为HMAC加密(对称加密), 用获得的公钥伪造HMAC签名, 服务端会用公钥进行验证
    注: 私钥相对难获取, 公钥相对易获取
  • 使用: 获得非对称加密公钥后, alg改为HS256, 用公钥伪造HS256签名, 传输
  • 注: 当伪造签名时, 公钥内容并非只有一行, 所以需要将换行符也算进去进行base64url编码后填入burpsuite的JWT Editor的k字段中

伪造签名

  • 工具: 使用burpsuite的JWT Editor工具
  • 普通:
    import jwt
    payload = {"alg":"None","typ":"jwt"}
    headers = {
    "iss":"admin","iat":1718865117,"exp":1718872317,"nbf":1718865117,"sub":"admin","jti":"503a4a179e5645e7be5c19a88450c618"
    }
    key = ""
    print(jwt.encode(payload, ,key algorithm="HS256", headers=headers))

KID参数注入

  • 前提: 服务端通过kid字段来决定校验的密钥
  • 原理: kid用于决定校验时使用的密钥文件, 若修改该字段的值, 可能造成 目录遍历漏洞/伪造签名/其它漏洞
  • 目录遍历: 将kid值修改为对应文件的路径, 对目录进行爆破
  • 伪造签名: 将kid设置为内容已知的文件的路径, 即可知道密钥, 从而伪造签名
    如将kid设置为/dev/null, 即可将密钥设置为空, 用空密钥伪造签名
  • 其它漏洞: 跟读取kid的方式有关系
    若密钥存在数据库中, 服务端通过数据库搜寻kid读取密钥, 则可能有SQL注入
    若密钥通过命令执行来读取, 而非文件函数, 则存在RCE漏洞

CVE-2022-39227

  • 简介: python_jwt<3.3.4时, 其库中的verify_jwt()函数身份验证可绕过
暂无评论

发送评论 编辑评论


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