JWT原理及利用

admin 2025年1月22日11:00:02评论8 views字数 2586阅读8分37秒阅读模式

JWT的结构包括三部分

头部(Header)负载(Payload) 和 签名(Signature)。它们之间使用点号“.”进行连接,构成了一个完整的JWT。

  1. 1. 头部(Header):通常包含两部分信息,一是指定该令牌使用的加密算法,例如HMAC SHA256或RSA;二是指定令牌的类型,即JWT。
  2. 2. 负载(Payload):用于存储包含用户信息、权限、过期时间等额外数据,这些数据是以JSON对象的形式存在的。负载也包含了一些预定义的标准声明,例如签发者(iss)、过期时间(exp)、主题(sub)、受众对象(aud)等。同时,负载也支持自定义声明。
  3. 3. 签名(Signature):用于验证JWT是否被篡改或伪造。在生成签名时,服务器会对头部和负载进行编码,并加上一个密钥进行数字签名。服务器在接收到客户端发送来的JWT后,会重新计算签名,并与原始签名进行比较以确认其有效性。

JWT 对象结构

这里可直接通过其官网进行Debugger,官方网站:https://jwt.io/

以官网提供的例子为例,JWT对象长这样:

JWT原理及利用

一个 JWT 对象由三个部分组成,以.进行分隔,所以上面这个JWT对象可以分为三部分:

代码语言:javascript

复制

`Header.Payload.Signature`
  • • Header(头部)eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • • Payload(负载)eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
  • • Signature(签名)SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header(头部)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9是一个Base64URL 编码后的数据,解码后得到的内容为:

JWT原理及利用

Header部分是一个JSON对象,描述JWT的元数据,其中有这几个参数:

  • • alg签名使用的算法 默认为HMAC SHA256( 简写为HS256
  • • typ用于标识该令牌(token)的类型为JWT

Payload(负载)

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ同样为Base64URL 编码后的数据。

{  "sub""1234567890",  "name""John Doe",  "iat"1516239022}

Signature(签名)

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c此处并不是Base64编码的数据。

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c计算过程:

首先,需要指定一个secret,这个密钥由服务器生成,只有服务器才知道,不能泄露给用户。然后,使用Header里面指定的签名算法(默认是HMAC SHA256),按照下面的公式产生签名。

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

针对 JWT 相关的攻击

未验证签名

未对签名进行校验,会导致攻击者随意篡改JWT的内容,从而造成越权等危害

由于后端没有对JWT的签名进行验证,可导致Payload字段遭到修改,以达到越权访问的目的。

修改RSA加密算法为HMAC

JWT中最常用的两种算法为HMACRSA

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,它是一种对称加密算法,使用相同的密钥对传输信息进行加解密。

RSA则是一种非对称加密算法,使用私钥加密明文,公钥解密密文。

在HMAC和RSA算法中,都是使用私钥对signature字段进行签名,只有拿到了加密时使用的私钥,才有可能伪造token。

现在我们假设有这样一种情况,一个Web应用,在JWT传输过程中使用RSA算法,密钥pem对JWT token进行签名,公钥pub对签名进行验证。

{``  ``"alg"` `: ``"RS256"``,``  ``"typ"` `: ``"jwt"``}

通常情况下密钥pem是无法获取到的,但是公钥pub却可以很容易通过某些途径读取到,这时,将JWT的加密算法修改为HMAC,即

{``  ``"alg"` `: ``"HS256"``,``  ``"typ"` `: ``"jwt"``}

同时使用获取到的公钥pub作为算法的密钥,对token进行签名,发送到服务器端。

服务器端会将RSA的公钥(pub)视为当前算法(HMAC)的密钥,使用HS256算法对接收到的签名进行验证。

修改KID参数

kid是jwt header中的一个可选参数,全称是key ID,它用于指定加密算法的密钥

{``  ``"alg"` `: ``"HS256"``,``  ``"typ"` `: ``"jwt"``,``  ``"kid"` `: ``"/home/jwt/.ssh/pem"``}

因为该参数可以由用户输入,所以也可能造成一些安全问题。

任意文件读取

kid参数用于读取密钥文件,但系统并不会知道用户想要读取的到底是不是密钥文件,所以,如果在没有对参数进行过滤的前提下,攻击者是可以读取到系统的任意文件的。

{``  ``"alg"` `: ``"HS256"``,``  ``"typ"` `: ``"jwt"``,``  ``"kid"` `: ``"/etc/passwd"``}

SQL注入

kid也可以从数据库中提取数据,这时候就有可能造成SQL注入攻击,通过构造SQL语句来获取数据或者是绕过signature的验证

{``  ``"alg"` `: ``"HS256"``,``  ``"typ"` `: ``"jwt"``,``  ``"kid"` `: ``"key11111111' || union select 'secretkey' -- "

参考文章

https://cloud.tencent.com/developer/article/2250580

原文始发于微信公众号(无尽藏攻防实验室):JWT原理及利用

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月22日11:00:02
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JWT原理及利用https://cn-sec.com/archives/3658808.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息