浅谈JWT安全问题

写在前头,总结向笔记类文章,内容有些不是我自己的,详情见参考资料
0x00 什么是JWT
 
JWT全称为: json  web token 
JWT通常用于实现前端和后端的解耦,同时,它还可以与Restful API一起使用,用于构建身份验证机制
 
0x01 JWT的格式

JWT的数据分为三部分:头部,有效载荷,签名(图来自freebuf一篇文章,具体找不到了)

 

 

 

通过base64编码起来
使用点号进行划分,比如一个JWT如:
eyJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJkdWJoZTEyMyJ9.XicP4pq_WIF2bAVtPmAlWIvAUad_eeBhDOQe2MXwHrE8a7930LlfQq1lFqBs0wLMhht6Z9BQXBRos9jvQ7eumEUFWFYKRZfu9POTOEE79wxNwTxGdHc5VidvrwiytkRMtGKIyhbv68duFPI68Qnzh0z0M7t5LkEDvNivfOrxdxwb7IQsAuenKzF67Z6UArbZE8odNZAA9IYaWHeh1b4OUG0OPM3saXYSG-Q1R5X_5nlWogHHYwy2kD9v4nk1BaQ5kHJIl8B3Nc77gVIIVvzI9N_klPcX5xsuw9SsUfr9d99kaKyMUSXxeiZVM-7os_dw3ttz2f-TJSNI0DYprHHLFw

1,头部

eyJraWQiOiJrZXlzLzNjM2MyZWExYzNmMTEzZjY0OWRjOTM4OWRkNzFiODUxIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ

解码为:

{“kid”:”keys/3c3c2ea1c3f113f649dc9389dd71b851",”typ”:”JWT”,”alg”:”RS256"}

包括了typ类型,alg:签名算法

 

2,有效载荷

eyJzdWIiOiJkdWJoZTEyMyJ9

有效载荷用来存储用户的数据,解码之后为

{"sub":"dubhe123"}

3,签名

XicP4pq_WIF2bAVtPmAlWIvAUad_eeBhDOQe2MXwHrE8a7930LlfQq1lFqBs0wLMhht6Z9BQXBRos9jvQ7eumEUFWFYKRZfu9POTOEE79wxNwTxGdHc5VidvrwiytkRMtGKIyhbv68duFPI68Qnzh0z0M7t5LkEDvNivfOrxdxwb7IQsAuenKzF67Z6UArbZE8odNZAA9IYaWHeh1b4OUG0OPM3saXYSG-Q1R5X_5nlWogHHYwy2kD9v4nk1BaQ5kHJIl8B3Nc77gVIIVvzI9N_klPcX5xsuw9SsUfr9d99kaKyMUSXxeiZVM-7os_dw3ttz2f-TJSNI0DYprHHLFw
由于头部和有效载荷以明文形式存储,因此,需要使用签名来防止数据被篡改。
提供数据的相关函数使用的签名算法通常是RS256(RSA非对称加密和私钥签名)和HS256(HMAC SHA256对称加密)算法。
如使用HS256的加密方式为:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

 

0X02 如何攻击JWT

1,敏感信息泄露
因为有效载荷是明文传输的,如果有效载荷存在敏感信息的话就会发生信息泄露
 
 
2,将签名算法改为none
使用工具: JWTPyCrack
python jwtcrack.py -m generate -s {\"admin\":\"True\"}

 

3,未校验签名

直接替换数据,使用https://jwt.io/#debugger
插入一些常见测试payload,如注入,xss等
 
4,爆破弱key
使用工具:JWTPyCrack ,只支持明文,有些时候可能还要考虑base64encode的情况,base64的情况,要自己编写脚本
python jwtcrack.py -m blasting -s eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU --kf 2.txt
除此之外,我们也可以用hashcat来爆破
爆破hahs少不了一个好的字典,而hashcat rules文件夹下其实有不少规则,我们也可以直接拿来用,生成字典:(b0b064.rule来源于Hob0Rules)
hashcat64.exe --stdout password.txt -r rules/hob064.rule -o pasword_new.txt --force

不想生成文件占磁盘,也可以直接用规则来爆破

hashcat64.exe -a 0 -m 16500 jwt_token jwt_key.txt -r rules/d3ad0ne.rule --force

当然也可以用掩码方式,爆破出来的时间取决于key的长度和GPU的性能

 

0x03 拓展:accessToken与refreshToken问题

风险点:
未校验access token和refresh token是否属于同一个用户,导致A用户可使用自己的refresh token去刷新B用户的access token,垂直越权

 

建议:
使用jwt令牌的最佳位置是服务器之间的通信。在普通的web应用程序中,最好使用普通的旧cookies。 
 
例子:
webgoat 8 ,使用A账号的refresh token 和 过期B的access_token去刷新 B的access_token
 
0x04 实战记录
1,开源程序默认key未修改

某众测厂商默认key直接伪造超级管理员进去

 

 github标志,开源系统直接跟过去

 

 有默认值,虽然作者再三提醒,但鉴于人的本质惰性,相信很多管理员都是不会去修改的,直接伪造超级管理员进去

 

 2,accessToken与refreshToken问题

某厂商可用A用户refreshToken刷新B用户的access_token
假如获取到B用户的过期access_token,那么就可以用A的refresh_token去刷新了
B用户的access_token与refresh_token
 

 

 使用A用户的refresh_token去刷新B用户的access_token

 

 正常B用户的请求

 

 替换之后的请求,成功请求

 

这里过期的access_token可以在搜索引擎搜到或者评论等信息泄漏

 

0x05 总结

简单列举了一下自己遇到的jwt两个案例,笔记向文章没啥好说的。

 

0x06 参考资料

posted @ 2020-03-17 20:15  水泡泡  阅读(...)  评论(...编辑  收藏