HACK TEH BOX - Under Construction(JWT金鑰混淆 + SQL隱碼攻擊)

Snowieee發表於2021-04-23

HACK TEH BOX - Under Construction(JWT金鑰混淆 + SQL隱碼攻擊)

1. JWT金鑰混淆

  JWT的組成一般分為三部分,{演算法}.{payload}.{簽名},例如加密函式中jwt.sign(data, privateKey, { algorithm:'RS256' })中,data為資料,privateKey為加密金鑰,{ algorithm:'RS256' }為加密演算法,JWT的一般形式和組成如下圖所示。

  JWT常用的兩種演算法是RSAHMAC,分別是非對稱演算法(一對金鑰)和對稱演算法(一個金鑰)。RS256演算法在服務端利用私鑰進行加密,利用公鑰來進行解密驗證資料。HS256演算法只擁有一個金鑰,用於加密和解密。考慮一種情況,如果在解密的過程中,解密的演算法被偽造,由RS256更改為HS256,那麼被用於HS256解密的金鑰就變為RS256中的公鑰,而由於公鑰的性質,可能會被攻擊者獲取,攻擊者在獲取到RS256的公鑰後,使用公鑰作為金鑰,利用HS256演算法進行加密,當JWT值傳送給服務端時,會被以HS256的方式進行解密,而解密的金鑰也是RS256公鑰,這樣攻擊者就可以偽造JWT中的payload值。
  下圖為題目中存在漏洞的程式碼,作為示例來介紹該漏洞
  
  示例程式碼中,加密過程使用的是RS256演算法,利用私鑰進行加密,但是在解密的函式中,同時提供了兩種演算法選項,這就表示如果使用HS256演算法進行解密,依然是使用公鑰作為金鑰,存在該漏洞。

2. 環境

  Hack The Box生成 Challenge環境(206.189.121.131:30520)  
  參考程式碼一份,包含內容如下
  

3. Challenge

  首先去環境看一下  
  一個簡單的登入頁面,註冊一個admin/123456的賬戶,再使用該賬戶登入,登陸後頁面跳轉
  註冊請求:  
  登入請求,返回JWT:  
  登陸成功,頁面跳轉:  
  登入頁面進行簡單的sql注入測試後,未發現注入點,F12瀏覽一下網站內資訊,沒有js檔案被載入,登入後被分配一個JWT值  
  拿去Burpsuite裡解密一下看看內容  
  RS256演算法,非對稱加密,但是在payload部分發現了公鑰資訊
  寫個簡單指令碼使用公鑰來解密一下資訊  
  執行成功,即JWT裡面的公鑰正確  
  目前就能獲取到這麼多資訊了,結合JWT內的公鑰資訊,可以大概猜出是利用JWT作為突破點進行攻擊
  接下來去看一下Challenge提供的網站原始碼,看有沒有什麼有用的資訊
  先去看看/routes/index.js路由檔案
  
  整個路由包含了以下幾個部分
    1.GET請求/
    2.GET請求/auth
    3.GET請求/logout
    4.POST請求/auth
  這四個部分的功能都非常的簡單,POST請求根據register欄位的值判斷登入/註冊,/logout清除session值,/auth返回auth.html頁面,在GET請求/時,需要先通過JWT內的值判斷使用者是否存在,再進行頁面跳轉或錯誤資訊,判斷過程首先要執行AuthMiddleware函式,返回成功後再執行DBHlper.getUser(username)函式,如果username在資料資料庫中存在的話,就會跳轉至index.html頁面,也就是登入後看到的頁面了。
  順著這個順序,首先先去看看AuthMiddleware.js檔案  
  大概功能就是返回JWT解碼後的username值,然後這個值就會被拿去DBHlper.getUser(username)函式比對
  接著去JWTHelper.js檔案  
  就是一個簡單的JWT加解密,但是在解密的過程中,同時支援了兩種演算法RSA256/HS256,這個地方就暴露出了漏洞——JWT金鑰混淆
  在進行完AuthMiddleware函式的流程後,進行下一步DBHlper.getUser(username)  
  在這個程式碼中,第一個sql語句使用了拼接字串的形式,後面的sql語句則是傳遞引數的形式,存在sql注入的漏洞
  到這裡就可以確定整個題目的思路了,首先GET請求/時,攜帶利用公鑰偽造的JWT,而JWT中的username欄位值為sql注入語句,執行後就可以進入資料庫查詢flag了。

4. Walkthrough

  寫指令碼利用公鑰作為金鑰進行HS256加密  
  報錯  
  檢視原始碼,發現被禁止使用公鑰來加密  
  直接去掉  
  在執行,返回值  
  拿著這個值去GET請求/驗證  
  驗證成功,返回index.html頁面,此時可以構造username欄位進行sql注入
  接下來結合JWT,寫一個sqlmaptamper指令碼  
  大概思路就是cookie值作為注入點,然後將payload寫進username欄位再進行加密作為cookie值傳遞
  tamper指令碼實現的過程只需要修改輸入引數payload,然後輸出retVal即可,如下圖所示
  
  執行程式碼時同樣報錯  
  改掉
  
  測試程式碼輸出成功,接下來進行指令碼編寫  
  寫好  
  上sqlmap測試        
拿到flagHTB{d0n7_3xp053_y0ur_publ1ck3y}

相關文章