今天繼續來介紹Authentication Flaws,接著就來看看JWT tokens的部分吧!
JSON Web Token (JWT)是一種網頁伺服器對於使用者進行身分驗證的機制,當初被發明出來是因應傳統使用Session及Token作為使用者端身分驗證的漏洞,而漏洞的詳細介紹可以參考「以 JSON Web Token 替代傳統 Token」這篇文章(網址:https://yami.io/jwt/ )。
JWT的長相如下圖,包含標頭 (Header)、內容 (Claims)及簽名 (Signature)三部分,三個部分分別以JSON格式描述內容,再以base64加密,並以「.」相連三個部分。
Header的部分包含加密類型 (alg)、類型定義 (typ)等,格式範例如下。
{
"alg":"HS256",
"typ":"JWT"
}
Claims的部分是自定義的內容,並沒有硬性規定一定要有哪些資訊,但是因為只要base64就可以把資訊解碼,所以不建議把機敏的資料留在這裡,格式範例如下。
{
"exp": 1416471934,
"user_name": "user",
"scope": [
"read",
"write"
],
"authorities": [
"ROLE_ADMIN",
"ROLE_USER"
],
"jti": "9bc92a44-0b1a-4c5e-be70-da52075b9a84",
"client_id": "my-client-with-secret"
}
Signature則是一個把以base64加密後的Header及Claims以「.」加起來後,再以只有伺服器才知道的秘鑰進行加密,內容範例如下。
qxNjYSPIKSURZEMqLQQPw1Zdk6Le2FdGHRYZG7SQnNk
而三個部分加起來並轉換為base64就會變成下列JWT格式。
JWT各個部分的內容詳細規範則可以參考RFC 7518的內容(網址:https://tools.ietf.org/html/rfc7518)。
接著來看看第4步的挑戰吧,在這個挑戰中,我們雖然沒有Admin的身分,但要JWT的特性,假冒為Admin並把所有的投票票數重置。
首先我們發現用Guest的角色什麼都不能操作,所以我們先改用Tom的角色來進行頁面操作。
接著我們試著在第一個項目進行投票,並用ZAP擷取到這個HTTP請求的Cookie包含了一個access_token,而且是JWT格式。
在這裡如果不想自己寫程式,可以利用一個叫做「JWT.io」的線上工具(網址:https://jwt.io/ )來把這串JWT進行解碼,並得到解碼出來的字串如下,從PAYLOAD的部分可以看到這串JWT是Tom使用的沒錯。
接著我們把admin從false改為true,並在密鑰的部分輸入WebGoat伺服器的秘鑰「victory」,並取得修正後的JWT,注意如果沒有輸入密鑰的話得出來的結果會是錯誤的喔。
至於「victory」這個密鑰是怎麼知道的呢?我是從WebGoat的github翻到的哈哈。(網址:https://github.com/WebGoat/WebGoat/blob/develop/webgoat-lessons/jwt/src/main/java/org/owasp/webgoat/plugin/JWTSecretKeyEndpoint.java )
然後我們把Cookie欄位裡的access_token參數值改成剛剛修正過的JWT並送出。
接著就順利過關啦。
這一題不一定要用Tom的帳號,用其他兩個人的帳號也都可以達到一樣的目的,步驟都是一樣的。
今天就先介紹到這邊啦,大家明天見。
參考資料:
[1] https://yami.io/jwt/
[2] https://tools.ietf.org/html/rfc7518