JWT相關漏洞介紹


JWT相關漏洞介紹

1、JWT基礎介紹

JWT常用於微服務,由於國內微服務常見於Java,所以JWT漏洞大都發生在Java應用中。

為什么用JWT?

JWT只通過算法實現對Token合法性的驗證,不依賴數據庫,Memcached的等存儲系統,因此可以做到跨服務器驗證,只要密鑰和算法相同,不同服務器程序生成的Token可以互相驗證,一旦我們掌握了token的構造,便可模仿任何已知用戶進行操作

以下面這段JWT token為例eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT令牌結構分為三部分,每部分中間使用點(.)分割,比如:xxxx.yyyyy.zzzzz

  • Header 頭部包括令牌的類型(即JWT)及使用的哈希算法(如HMAC SHA256或RSA)

  • payload

    第二部分是負載,內容也是一個json對象,它是存放有效信息的地方,它可以存放jwt提供的現成字段,比 如:iss(簽發者),exp(過期時間戳), sub(面向的用戶)等,也可自定義字段。

  • Signature

    第三部分是簽名,此部分用於防止jwt內容被篡改。

image-20220324160511996

jwt_token

2、漏洞一(alg: none攻擊)

每個JWT令牌應該在返回給客戶端之前進行簽名,如果令牌未簽名,則客戶端將能夠更改令牌內容,從而造成越權操作。

推薦工具:jwt_tool.py

alg:none攻擊通俗易懂的講就是由於開發代碼使用錯誤,后端不校驗簽名,導致攻擊者可以在不需要密鑰的情況下也可以控制偽造令牌。

image-20220324165642633

實驗1:

題目要求:嘗試修改令牌成為管理員用戶,然后重置投票數(只有管理員可以修改)

抓包發送看看結果,可以看到提示只有admin用戶才可以重置

image-20220324163112614

將token解密

eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2NDg5NzM3NDAsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.-55OhNElIUr5xMJS2U0k0o0t-Li2VSExwjoFf2CrQFi3XLjwcelAu1yN-7L0bnPk_EFOEgPXsa8ItaTNNn44aw

image-20220324162739996

黑盒測試第一反應肯定是將"admin" : "false"修改為"admin" : "true",嘗試將tom設置為admin權限。由於我們提前看過代碼了,可以利用alg:none攻擊

python jwt_tool.py eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2NDg5NzM3NDAsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.-55OhNElIUr5xMJS2U0k0o0t-Li2VSExwjoFf2CrQFi3XLjwcelAu1yN-7L0bnPk_EFOEgPXsa8ItaTNNn44aw -T

image-20220324164159464

將生成的token帶入cookie繞過獲得admin權限

image-20220324165157212

修復建議:

驗證令牌時使用正確代碼:使用parseClaimsJws獲取token,禁止使用parse獲取。

課堂作業

代碼片段一

try {
    Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parseClaimsJws(accessToken);
    Claims claims = (Claims) jwt.getBody();
    String user = (String) claims.get("user");
    boolean isAdmin = Boolean.valueOf((String) claims.get("admin"));
    if (isAdmin) {
      removeAllUsers();
    } else {
      log.error("You are not an admin user");
    }
 } catch (JwtException e) {
   throw new InvalidTokenException(e);
 }

代碼片段二

 try {
    Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken);
    Claims claims = (Claims) jwt.getBody();
    String user = (String) claims.get("user");
    booelean isAdmin = Boolean.valueOf((String) claims.get("admin"));
    if (isAdmin) {
      removeAllUsers();
    } else {
      log.error("You are not an admin user");
    }
 } catch (JwtException e) {
   throw new InvalidTokenException(e);
 }

哪一段代碼具有漏洞風險

3、漏洞二(密鑰爆破)

我們知道JWT分為三部分,前兩部分由base64編碼而成,而第三部分由第一部分的加密方式及key加密而成,當應用不存在alg:none漏洞時,我們需要key才能構造一個完整可用的token。此處介紹token的密鑰破解,關鍵在於字典要龐大。

實驗2:嘗試修改下面token,使其成為WebGoat用戶的token

eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTY0ODEwOTI1NywiZXhwIjoxNjQ4MTA5MzE3LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.xtDJKmWvAH-pleTEnDuOkOC0PbCE9IU9854oS1FiLTA

image-20220324170305968

我們使用工具嘗試爆破key

image-20220324170634370

可以看到key的結果為shipping,將key帶入並修改username參數為WebGoat,記住token有效期為1分鍾

image-20220324170847329

image-20220324170918143

image-20220324171113338

可以看到密鑰硬編碼在代碼中

修復建議:

1、使用強密鑰,滿足密碼構成需求

2、代碼中不要出現硬編碼,一旦代碼泄露造成認證失效,見shiro550硬編碼漏洞

4、漏洞三(令牌刷新)

該漏洞偏向邏輯漏洞

在實際工作中較難碰到,需要有刷新令牌的功能

實驗3:模擬tom為相關產品付費。需要結果代碼審計

首先模擬Jerry登錄

image-20220324172013463

image-20220324171937362

image-20220324172123577

第二個接口說明可以使用alg:none攻擊從而繞過認證,我們嘗試將其修改

image-20220324172543791

成功了,但該題並不是想讓我們學習alg:none攻擊

看到第三個接口

image-20220324172635939

我們繼續看第三段接口

image-20220324173926359

僅校驗是否存在user和refreshToken,未校驗兩者對應關系,可以用來刷新任何用戶的過期token。思路:先用Jerry用戶登錄獲取Jerry的token,利用newtoken接口刷新Tom過期的接口獲得新的token,最后使用獲得的新的token進行銷賬。

利用步驟

image-20220324180741981

image-20220324180909995

image-20220324180958034

JWT還有SQL注入、XXE等利用方式,由於結合了多種漏洞形式,剛接觸的人可能接受不了,后續有機會再了解。

總結

1、用parseClaimsJws獲取token,禁止使用parse獲取

2、禁止使用弱密鑰、嘗試將密鑰寫進數據庫,不要硬編碼寫在代碼里

3、調用刷新token的接口時做好用戶名與token的校驗


免責聲明!

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



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