1. 程式人生 > 實用技巧 >CTFHub題解-技能樹-Web進階-JSON Web Token 【敏感資訊洩露、無簽名】

CTFHub題解-技能樹-Web進階-JSON Web Token 【敏感資訊洩露、無簽名】

CTFHub題解-技能樹-Web進階-JSON Web Token(敏感資訊洩露、無簽名、弱金鑰)

題外話:emmmm,停更了辣麼久......我又厚臉皮回來更新了,哈哈哈哈哈~(。・∀・)ノ゙

(一)敏感資訊洩露

1.知識點

* 先來了解一下 使用者認證流程 (1)使用者向伺服器傳送使用者名稱和密碼。 (2)伺服器驗證通過後,在當前對話(session)裡面儲存相關資料,比如使用者角色、登入時間等等。 (3)伺服器向用戶返回一個 session_id,寫入使用者的 Cookie。 (4)使用者隨後的每一次請求,都會通過 Cookie,將 session_id 傳回伺服器。 (5)伺服器收到 session_id,找到前期儲存的資料,由此得知使用者的身份。
JSON Web Token(縮寫 JWT),伺服器認證以後,生成一個 JSON 物件,發回給使用者。   以後,使用者與服務端通訊的時候,都要發回這個 JSON 物件。   伺服器完全只靠這個物件認定使用者身份。   為了防止使用者篡改資料,伺服器在生成這個物件的時候,會加上簽名。 JWT 的結構 由三部分構成: Header.Payload.Signature 頭部.負載.簽名 舉個栗子~ JWT大概就是這種形式: 頭部:eyJBRyI6IjNmMjhhYzg3NTA2M2JmMn0iLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9. 負載:eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJGTCI6ImN0Zmh1Yns5ODMzZTE1NzQifQ.
簽名:jFf_cb3Fx3EkOwrTR4ro_a3lMAq3Rd44mfJ8Pih6DqI 它是一個很長的字串,中間用點 . 分隔成三個部分。 Header 部分是一個 JSON 物件,描述 JWT 的元資料。 Payload 部分也是一個 JSON 物件,用來存放實際需要傳遞的資料。 Signature 部分是對前兩部分的簽名,防止資料篡改。這裡需要指定一個金鑰(secret)。這個金鑰只有伺服器才知道,不能洩露給使用者。然後,使用 Header 裡面指定的簽名演算法(預設是 HMAC SHA256)。 注意:Header Payload 串型化的演算法是 Base64URL
JWT 作為一個令牌(token),有些場合可能會放到 URL(比如 api.example.com/?token=xxx)。Base64 有三個字元+、/和=,在 URL 裡面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。 JWT的特點
(1)JWT 預設是不加密,但也是可以加密的。 (2)JWT 不加密的情況下,不能將祕密資料寫入 JWT。 (3)JWT 不僅可以用於認證,也可以用於交換資訊。有效使用 JWT,可以降低伺服器查詢資料庫的次數。 (4)JWT 簽發了,在到期之前就會始終有效,因為伺服器不儲存 session 狀態,因此無法在使用過程中廢止某個 token,或更改 token 的許可權。 (5)JWT 本身包含了認證資訊,一旦洩露,任何人都可以獲得該令牌的所有許可權。 (6)JWT 不應該使用 HTTP 協議明碼傳輸,要使用 HTTPS 協議傳輸。

2.題解

開啟時候發現是個登入框,先抓個包看看吧~ 我們看到Responsetoken是這個樣子的: eyJBRyI6IjNmMjhhYzg3NTA2M2JmMn0iLCJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJGTCI6ImN0Zmh1Yns5ODMzZTE1NzQifQ.jFf_cb3Fx3EkOwrTR4ro_a3lMAq3Rd44mfJ8Pih6DqI 拿去進行base64url解碼: 可以用burp自帶的解碼器Decoder 也可以用 解碼網站:https://base64.us/# 看到解碼結果,發現了ctfhub的字樣,emmmm,只有一半........ 那麼另一半.........再仔細看看結果,原來在解碼結果的前半段~ 拼起來就可以了~ ctfhub{9833e15743f28ac875063bf2}

(二)無簽名

1.知識點

JWTBase64Url的知識點可以參考上面一道題哦~

2.題解

Go一下看看情況: 先把token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJyb2xlIjoiZ3Vlc3QifQ.MaphZVk25q4stXxAmEgXmKCW7aUo3jDJtgv9DwahLwc;粘下來。 直接用burp自帶的Decoder進行base64url解碼吧~ 解出來的結果是這個:
{"typ":"JWT","alg":"none"}.{"username":"admin","password":"123456","role":"admin"fQ.1ªaeY6æ®,µ|@H í¥(Þ0ɶý¡Lwc

從題目提示可以知道:一些JWT庫也支援none演算法,即不使用簽名演算法。當alg欄位為空時,後端將不執行簽名驗證 先解碼 頭部 接著將 HS256演算法修改成none 演算法。 轉碼~ JWT 作為一個令牌(token),有些場合可能會放到 URL(比如 api.example.com/?token=xxx)。Base64 有三個字元+、/和=,在 URL 裡面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。 eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0= 接著解碼 負載 這裡沒有顯示},可能是因為等號= 省略的原因,我們可以先加上 eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4ifQ== 解碼出來是
{"username":"admin","password":"123456","role":"guest"}
這裡將guest 修改成 admin 轉碼~ 好啦~ 把 頭部 和 負載 拼起來,記得 負載 後的 . 要加上喲~ 原始JWT: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJyb2xlIjoiZ3Vlc3QifQ.MaphZVk25q4stXxAmEgXmKCW7aUo3jDJtgv9DwahLwc 修改none演算法admin的JWT: eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4ifQ==. 然後我們把token替換到Request裡面,Go一下 emmmmm.....怎麼沒有flag呢? 仔細看一下跳轉的頁面,是.../index.php 那就把Request的這部分修改一下吧~ POST /index.php HTTP/1.1 Go一下,看到 flag 啦~ ctfhub{d888243961e7b9e90c321e37}

參考資料:

https://jwt.io/introduction/ http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html https://blog.csdn.net/rfrder/article/details/108619373