JWT攻擊手冊:如何入侵你的Token


JSON Web Token(JWT)對於滲透測試人員而言,可能是一個非常吸引人的攻擊途徑。因為它不僅可以讓你偽造任意用戶獲得無限的訪問權限,而且還可能進一步發現更多的安全漏洞,如信息泄露,越權訪問,SQLi,XSS,SSRF,RCE,LFI等。
首先我們需要識別應用程序正在使用JWT,最簡單的方法是在代理工具的歷史記錄中搜索JWT正則表達式:

[= ]ey[A-Za-z0-9_-]*\.[A-Za-z0-9._-]*         -網址安全的JWT版本
[= ]ey[A-Za-z0-9_\/+-]*\.[A-Za-z0-9._\/+-]*   -所有JWT版本(可能誤報)

確保選中“區分大小寫”和“正則表達式”選項:


當你獲得一個JSON web token,如何利用它們繞過訪問控制並入侵系統?

1、敏感信息泄露

由於Header和Payload部分是使用可逆base64方法編碼的,因此任何能夠看到令牌的人都可以讀取數據。
要讀取內容,您只需要將每個部分傳遞給base64解碼函數,以下是一些示例:
Linux base64工具(帶有-d標志用於解碼):

$ echo eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 | base64 -d
 {"typ":"JWT","alg":"HS256"}

瀏覽器JavaScript控制台:

>> atob("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9")
 "{"typ":"JWT","alg":"HS256"}"

Powershell:

PS C:\> [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64Strin
g("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"))
{"typ":"JWT","alg":"HS256"}

Pyhton:

>>> import base64
>>> print(base64.b64decode('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9'))
{"typ":"JWT","alg":"HS256"}

我曾在一篇博文中,不小心公布了有漏洞指向站點的Token,分分鍾被找到了漏洞站點。因此,Token不能隨意公布,發送的數據不得包含任何敏感數據(例如密碼)。

2、將算法修改為none

JWT支持將算法設定為“None”。如果“alg”字段設為“ None”,那么簽名會被置空,這樣任何token都是有效的。
設定該功能的最初目的是為了方便調試。但是,若不在生產環境中關閉該功能,攻擊者可以通過將alg字段設置為“None”來偽造他們想要的任何token,接着便可以使用偽造的token冒充任意用戶登陸網站。
示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJ1cGxvYWQifQ.y2k9SJDRU81ybXm-anxpD2p1N-rKekDJtJGKGJlemjY

設置 “alg”: “none”不帶簽名,生成Token:

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJ1cGxvYWQifQ.

解構:

{"typ":"JWT","alg":"none"}.
{"user":"admin","action":"upload"}.
[No signature!]

頁面是否仍然返回有效?如果頁面返回有效,那么說明存在漏洞。
如何抵御這種攻擊? JWT配置應該指定所需的簽名算法,不要指定”none”。

3、密鑰混淆攻擊

JWT最常用的兩種算法是HMAC和RSA。HMAC(對稱加密算法)用同一個密鑰對token進行簽名和認證。而RSA(非對稱加密算法)需要兩個密鑰,先用私鑰加密生成JWT,然后使用其對應的公鑰來解密驗證。
如果將算法RS256修改為HS256(非對稱密碼算法=>對稱密碼算法)?
那么,后端代碼會使用公鑰作為秘密密鑰,然后使用HS256算法驗證簽名。由於公鑰有時可以被攻擊者獲取到,所以攻擊者可以修改header中算法為HS256,然后使用RSA公鑰對數據進行簽名。
示例:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpbiI6InRpY2FycGkifQ.I3G9aRHfunXlZV2lyJvWkZO0I_A_OiaAAQakU_kjkJM

解構:

{"typ":"JWT","alg":"HS256"}.
{"login":"ticarpi"}.
[使用HS256簽名,使用RSA公鑰文件作為密鑰驗證。]

后端代碼會使用RSA公鑰+HS256算法進行簽名驗證。
如何抵御這種攻擊?JWT配置應該只允許使用HMAC算法或公鑰算法,決不能同時使用這兩種算法。

4、無效簽名

當用戶端提交請求給應用程序,服務端可能沒有對token簽名進行校驗,這樣,攻擊者便可以通過提供無效簽名簡單地繞過安全機制。
示例:
一個很好的例子是網站上的“個人資料”頁面,因為我們只有在被授權通過有效的JWT進行訪問時才能訪問此頁面,我們將重放請求並尋找響應的變化以發現問題。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoidGVzdCIsImFjdGlvbiI6InByb2ZpbGUifQ.FjnAvQxzRKcahlw2EPd9o7teqX-fQSt7MZhT84hj7mU

user 字段改為 admin,重新生成新 token:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJwcm9maWxlIn0._LRRXAfXtnagdyB1uRk-7CfkK1RESGwxqQCdwCNSPaI

結構:

{"typ": "JWT", "alg": "HS256"}.
{"user": "admin","action": "profile"}.
[新的簽名]

將重新生成的Token發給服務端效驗,如訪問頁面正常,則說明漏洞存在。

5、暴力破解密鑰

HMAC簽名密鑰(例如HS256 / HS384 / HS512)使用對稱加密,這意味着對令牌進行簽名的密鑰也用於對其進行驗證。由於簽名驗證是一個自包含的過程,因此可以測試令牌本身的有效密鑰,而不必將其發送回應用程序進行驗證。
因此,HMAC JWT破解是離線的,通過JWT破解工具,可以快速檢查已知的泄漏密碼列表或默認密碼。

python jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4iLCJhY3Rpb24iOiJ1cGxvYWQifQ.7ZbwdZXwfjm575fHGukkE09O8-eFY4bx-fEEBUK3XUE -C -d 1.txt

獲得密鑰,偽造任意用戶的Token:



如果可以破解HMAC密鑰,則可以偽造令牌中的任何內容,這個漏洞將會給系統帶來非常嚴重的后果。

6、密鑰泄露

假設攻擊者無法暴力破解密鑰,那么他可能通過其他途徑獲取密碼,如git信息泄露、目錄遍歷,任意文件讀取、XXE漏洞等,從而偽造任意token簽名。

7、操縱KID

KID代表“密鑰序號”(Key ID)。它是JWT頭部的一個可選字段,開發人員可以用它標識認證token的某一密鑰。KID參數的正確用法如下所示:

{
    "alg": "HS256",
    "typ": "JWT",
    "kid": "1"        //使用密鑰1驗證token
}

由於此字段是由用戶控制的,因此攻擊者可能會操縱它並導致危險的后果。

目錄遍歷
由於KID通常用於從文件系統中檢索密鑰文件,因此,如果在使用前不清理KID,文件系統可能會遭到目錄遍歷攻擊。這樣,攻擊者便能夠在文件系統中指定任意文件作為認證的密鑰。

"kid": "../../public/css/main.css"   //使用公共文件main.css驗證token

例如,攻擊者可以強行設定應用程序使用公開可用文件作為密鑰,並用該文件給HMAC加密的token簽名。

SQL注入
KID也可以用於在數據庫中檢索密鑰。在該情況下,攻擊者很可能會利用SQL注入來繞過JWT安全機制。
如果可以在KID參數上進行SQL注入,攻擊者便能使用該注入返回任意值。

"kid":"aaaaaaa' UNION SELECT 'key';--"  //使用字符串"key"驗證token

上面這個注入會導致應用程序返回字符串“ key”(因為數據庫中不存在名為“ aaaaaaa”的密鑰)。然后使用字符串“ key”作為密鑰來認證token。

命令注入
有時,將KID參數直接傳到不安全的文件讀取操作可能會讓一些命令注入代碼流中。
一些函數就能給此類型攻擊可乘之機,比如Ruby open()。攻擊者只需在輸入的KID文件名后面添加命令,即可執行系統命令:

"key_file" | whoami;

類似情況還有很多,這只是其中一個例子。理論上,每當應用程序將未審查的頭部文件參數傳遞給類似system(),exec()的函數時,都會產生此種漏洞。

8、操縱頭部參數

除KID外,JWT標准還能讓開發人員通過URL指定密鑰。

JKU頭部參數
JKU全稱是“JWKSet URL”,它是頭部的一個可選字段,用於指定鏈接到一組加密token密鑰的URL。若允許使用該字段且不設置限定條件,攻擊者就能托管自己的密鑰文件,並指定應用程序,用它來認證token。

jku URL->包含JWK集的文件->用於驗證令牌的JWK

JWK頭部參數
頭部可選參數JWK(JSON Web Key)使得攻擊者能將認證的密鑰直接嵌入token中。

操縱X5U,X5C URL

同JKU或JWK頭部類似,x5u和x5c頭部參數允許攻擊者用於驗證Token的公鑰證書或證書鏈。x5u以URI形式指定信息,而x5c允許將證書值嵌入token中。

攻擊Token的過程顯然取決於你所測試的JWT配置和實現的情況,但是在測試JWT時,通過對目標服務的Web請求中使用的Token進行讀取、篡改和簽名,可能遇到已知的攻擊方式以及潛在的安全漏洞和配置錯誤,希望本文可以幫助你發現安全威脅!

參考資料:

https://github.com/ticarpi/jwt_tool/wiki

https://medium.com/swlh/hacking-json-web-tokens-jwts-9122efe91e4a


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM