JWT(json web token)的底层组成部分
1.Header(头) 作用:记录令牌类型、签名算法等 例如:{“alg":"HS256","type","JWT}
2.Payload(有效载荷)作用:携带一些用户信息 例如{"userId":"1","username":"mayikt"}
3.Signature(签名)作用:防止Token被篡改、确保安全性 例如 计算出来的签名,一个字符串
1.第一部分:header (头部)
{
Typ=“jwt” —类型为jwt
Alg:“HS256” --加密算法为hs256//主要是用于验签,防止数据被篡改
}
2.第二部分:playload(有效载荷) 携带存放的数据 用户名称、用户头像之类 注意敏感数据
标准中注册的声明 (各个字段代表的含义,根据需求进行篡改) :
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
iat: jwt的签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
exp: jwt的过期时间,这个过期时间必须要大于签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
3.第三部分:Signature(签名)
最后的Signature是为了防止对两部分内容进行数据篡改,而采用的安全措施。服务器会存有一个密钥,然后使用header里面指定的签名算法(默认为SHA256),按照以下公式来产生签名。
最后把三个部分采用base64url编码进行加密,拼接为字符串,每个部分用点 . 分割,然后传给用户
ps://base64url编码加密是先做base64加密,然后再将 + 改成 -、 / 改成 _ ,同时也去除末尾额外添加的 = 字符
例题:
点击查看flag的界面,但是发现无法查看
一、于是利用burpsuite抓包获取到原token字符串:
放入到专门处理JWT字符串的在线工具中,但还没有获取到签名(密钥),根据反馈信息提示直接单纯更改username依然无法通过
二、利用python运行crackjwt.py脚本工具获取到JWT签名(密钥)
在这里我们使用方法的是利用github上的jwtcrack进行字典爆破,可用的字典也已经在服务器反馈中给出提示:https://github.com/first20hours/google-10000-english
在使用python脚本运行之前,需要先安装第三方库:pyjwt、tqdm
(注意不要连接校园网的情况去下载,会被ban)
pip install pyjwt tqdm
将要破解的jwt字符串复制放入hell.txt中,并将其放入脚本工具的同一级文件夹,然后cmd进入命令行,输入python命令
python crackjwt.py xxx.txt gogle-10000-english.txt
得到密钥:happy
三、获取到密钥后填入到第三部分签名中,并将username字段更改为服务器要求的"Sonder"
将转换得到的JWT字符串替换原JWT字符串,发送给服务器端,但是发现因为exp(jwt的过期时间)的问题仍然无法获取flag,但此时已经成功一大半了
四、利用时间戳转换工具,进行将payload中的exp字段的时间进行转换
将转换好的时间数字串替换原exp字段的数字串
将转换得到的JWT字符串替换原字符串,发送给服务器端成功得到flag
Reference: