1、什么是JWT
参考文章:https://www.jianshu.com/p/576dbf44b2ae
2、JWT验证绕过
在渗透过程中,通过观察token验证的值,可能在Cookie或者Authorization字段中,如果是iii.mmm.zzz的形式,说明是采用jwt加密,可以尝试几种方法进行绕过
jwt在线解密:https://jwt.io/
1、直接修改jwt令牌进行权限提升
webgoat靶场--jwt token —4
需要重置投票,而只有管理员才有权限重置

点击垃圾箱重置投票,由于是guest用户,所以无法获取令牌
选择Tom用户又提示只有管理员才能重置

用bp抓包查看jwt令牌
其中Cookie的access_token为jwt令牌的形式,iii.mmm.zzz
复制到https://jwt.io/解密

第一部分声明加密方法为HS512
第二部分声明用户名和权限,可以看到管理员权限为false
绕过:
将admin改为true,由于加密方法是HS512,且不知道秘钥,所以只能将alg的值改为none,即无加密方法
然后将修改后的第一第二部分用base64加密再去=号,重新拼接成伪造的jwt进行权限提升


由于是无加密,所以第二部分为空,成功重置

2、利用过期令牌进行伪造
webgoat靶场--jwt token—5
需要利用历史令牌找出秘钥,并得到新的秘钥,将用户名改为WebGoat

输入题目给的令牌提示JWT已过期
利用脚本或者hashcat爆破秘钥
jwt_find_miyao.py
import jwt
import termcolor
jwt_str = R"eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJhdWQiOiJ3ZWJnb2F0Lm9yZyIsImlhdCI6MTY0MDg0MDg1NywiZXhwIjoxNjQwODQwOTE3LCJzdWIiOiJ0b21Ad2ViZ29hdC5vcmciLCJ1c2VybmFtZSI6IlRvbSIsIkVtYWlsIjoidG9tQHdlYmdvYXQub3JnIiwiUm9sZSI6WyJNYW5hZ2VyIiwiUHJvamVjdCBBZG1pbmlzdHJhdG9yIl19.7HdANKeLioK-GsBUY9af80gODrlkFURDDE6u0LbmWZw"
with open("20k.txt") as f:
for line in f:
key_ = line.strip()
try:
jwt.decode(jwt_str, verify=True, algorithms="HS256", key=key_)
print('\r', '找到秘钥--->', termcolor.colored(key_, "green"), "<---")
break
except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuerError, jwt.exceptions.ImmatureSignatureError):
print('\r', '找到秘钥--->', termcolor.colored(key_, "green"), "<---")
break
except jwt.exceptions.InvalidSignatureError:
print('\r', ' ' * 64, '\r\btry', key_, end='', flush=True)
continue
else:
print('\r', '\b抱歉!没找到秘钥')

秘钥为:victory
利用秘钥重新获取jwt令牌https://jwt.io/, 用户名改为WebGoat,并延长时间戳到未过期

将得到的令牌填入
成功伪造令牌
3、利用历史令牌伪造
webgoat靶场--jwt token —7
在这关中,当前用户是Jerry,需要用tom的身份去付款,题目给出了一个日志记录,其中记录了一个jwt令牌,通过解密知道是tom的历史令牌


点击Checkout抓包,通过Authorization字段进行验证,加密方法是jwt

利用日志记录tom的历史令牌,将header头部的alg改为none,第二部分时间戳延长到未过期,再进行base64加密去=号(同第4关类似)

换成伪造的jwt令牌成功绕过

4、sql注入绕过key
webgoat靶场--jwt token —8



通过分析源码header部分的kid字段存在sql注入

通过传入的kid作为id值查询jwt_keys表,将查询到的key进行base64解码,然后作为秘钥进行token解析验证
通过构造sql语句,使查询得到的结果是可控的,如下

所以可以采用union注入或堆叠注入,查询到的key要经过base64解码,所以需要将自定义的key编码之后再代入
如下: base64编码:imz--->aW16
然后秘钥输入自定义的imz得到伪造的令牌

成功伪造
