JWT(JSON Web?Token)
從其名字就可以看出來,它具有表示身份的作用,其本質是將用戶信息儲存到一串json字符串中再將其編碼得到一串token
JWT由三部分組成,分別是
Header,Payload,Signatrue
JWT=Base64(Header).Base64(Payload).加密函數(base64UrlEncode(header)+"."+base64UrlEncode(payload),secret)
例如:?
Header部分
{
"kid":"4ff7ccb9-58a2-47de-8f91-cfc7582ebe41",
"alg":"RS256"
}
?Payload部分
{
"iss":"portswigger",
"exp":1745253912,
"sub":"administrator"
}
Signature部分
#一大堆加密后的信息(簽名)
u9e8ddhECxkGzuvGk9u78LcmBmLK4apCDh84l2BgYjauMcWkzSF2A9rqDEzqdBDiBMyHkUYeLiVF7Nu7km94PfMskQlIeVxuSF0MxI3a7I53mJ7woT3ypQm3Jw6VAOlqapLEC7VRa3Vfgv7H_dJpbFJkrHwE9KfW3TzdQeVAz-QKglJritq5WAPXP4oGAu5lSK8QUVECvUcnTYYzGS_TYYuOewbqgiq1w_dm5wn0M1LEYu1QM1fu7l8kOcDnkw7nMxeBM3iiZpAESvhd2myN_MCuIFFkC5OKghsWqIRehMKG3qR1X2YWnem04_ki6YMRA1jqEcvp5acH58rhGrDEyQ
1.JWT authentication bypass via unverified signature
本關要求我們進入管理員界面/admin并且刪除用戶carlos
我們訪問admin,會發現提示只有administrator可以訪問
那么我們登錄wiener用戶并且抓包,在放行了第一個包后第二個抓到的包就是我們所要的包
我們要去到管理員的/admin界面,就需要以管理員身份去訪問
先登錄到我們的賬號wiener
這一步的目的是先讓我們得到自己的cookie以查看jwt信息以讓我們可以去分析其構成
再訪問/admin界面,同時抓包
我們在burp里雙擊jwt的內容可以在inspector欄里看到對應的信息以及對應的解碼結果,這里我們就查看payload信息,也就是第一個句點.后的內容,可以看到里面有個sub參數對應的值為wiener
我們將其修改為administrator后應用
再放行這個包會發現訪問/admin成功,網站將我們認成了administrator
我們要刪除carlos用戶,執行刪除操作也要以管理員的身份執行,具體方法和前面一樣,抓包修改jwt信息為administrator
放行后成功過關
2.JWT authentication bypass via flawed signature verification
本關要求也和上一關一樣要去/admin里刪除carlos
但是本關還會校驗jwt里的簽名信息,所以單單修改用戶名是沒有用的,我們還是先登錄wiener用戶然后訪問/admin再抓包
修改payload部分里的用戶名為administrator
再修改header里的加密方式為none
修改為none后我們需要把jwt里的簽名信息給刪掉,但別把句點.也刪了,不然jwt格式錯誤
隨后放行,發現成功訪問admin界面
刪除carlos時也要重復前面一樣的操作
放行后成功過關
3.JWT authentication bypass via weak signing key
本關要求也一樣是刪除carlos
同時將簽名加密類型修改為none給過濾掉了,也就是不得不破解加密用的密鑰了,并且本關也是提示弱簽名,可以爆破
同樣的步驟登錄賬號,訪問/admin然后抓包,此時將jwt信息復制出來,使用hashcat工具破解
使用命令
hashcat -a 0 -m 16500 <jwt信息> <爆破字典>
得到密鑰為secret1
于是前往json編輯網站JSON Web Tokens - jwt.io進行修改
將原有的jwt復制進去后修改decoded的內容,encoded的內容就是我們要的
將其替換原有的jwt
放行后成功繞過驗證
再以一樣的操作刪除carlos用戶
放行后成功過關
4.JWT authentication bypass via jwk header injection
本關也一樣要求在/admin下刪除carlos
并且本關也同樣限制了none加密方式,同時加密很復雜很難爆破,那么根據本關題目提示,應該是通過修改jwt的header部分實現繞過,題目提示服務器支持jwk也就是JSON Web Key,它可以作為jwt里header的一部分,在這里用于數字簽名身份驗證
一下就是一串jwk結構(以RSA為例)
{"kty": "RSA", // 密鑰類型(RSA/EC/oct)"alg": "RS256", // 算法(如 RS256、ES256、HS256)"kid": "2023-01", // 密鑰唯一標識(用于輪換)"n": "Modulus...", // RSA 模數(Base64URL)"e": "AQAB", // RSA 公鑰指數(通常為 65537)"d": "PrivateExponent", // 私鑰參數(僅私鑰包含)"p": "Prime1", // 私鑰參數(僅私鑰包含)"q": "Prime2", // 私鑰參數(僅私鑰包含)"use": "sig", // 用途(sig 簽名/enc 加密)
}
如果服務器沒有對用于驗證的公鑰做篩選(比如白名單),我們可以通過構造管理員的簽名來欺騙服務器認為我們是administrator
一樣我們先登錄wiener,然后抓取前往/admin的包
我們這里要先安裝一個burp插件叫做JWT editor
安裝后我們抓的包會發現多了一欄選項叫做json web token也就是jwt
我們要構造jwk,就需要用到jwt editor來生成一個rsa密鑰
進入jwt editor界面在右邊選擇new rsa key
選擇類型為JWK,然后生成
隨后我們要先修改我們的身份信息為administrator
然后在json web token欄內的攻擊方式里選擇Embedded JWK(嵌入式JWK)
注意要先修改身份信息在配置攻擊方式,不然jwk驗證出來會是修改之前的wiener
隨后選擇我們剛生成的rsa密鑰,通過kid來選擇
確認后可以看到我們的JWT信息已經被修改
隨后放行,發現我們已經成功進入/admin了
然后刪除carlos,也使用和前面一樣的操作,密鑰就不用重新生成了
注意要先修改身份信息再配置攻擊模式
放行后成功過關