Esempio n. 1
0
    def test_rs256_signature2(self):
        rsa256_token_header = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImprdSI6Imh0dHBzOi8vd2ViaG9vay5zaXRlLzQ4MjAzNjZlLTRhY2YtNDQ5Mi04YjhiLTJmZDRlMGIyNmJlMiJ9"
        rsa256_token_payload = "eyJ1c2VyIjoiYWRtaW4ifQ"
        rsa256_token_signature = "lJSuLrAA6goQ5f2AXYXV25xZ66yuE_aRQlRpTpirSbVN7SxMOFooPkPIywejg1F5F89vFmibY_ATqu5bvyFjX1dIbb-PPFBSyB3AwgeLGq_UXSyRjf2WEw-UWYxq00l6b3f8qOI2nuS8Ea3iy5xfGqc6geUXXtJZN02o-QWoZ0qZ6vECrL3__dwbFQDLdgIw_TPYzrVjjLk69islxE8Vv9G5ZOAtwFZrzcZuTQTMTRJrpMNstuX4gYeJOu7VUWzKoQjT4D_PUX4mB_Sn80JyVMHPjcse_ZtHSkWgse86Gx0-Tmv7B7tqTXNtNfugctrkUxwZM2b0k4XYErnycXK-Bg"
        rsa_token_ser = ".".join([
            rsa256_token_header, rsa256_token_payload, rsa256_token_signature
        ])
        rsa_token = TestJWT.TestJWT.deserialize(rsa_token_ser)

        self.assertEqual("RS256", rsa_token.header['alg'])
        self.assertEqual("JWT", rsa_token.header['typ'])
        self.assertEqual(
            "https://webhook.site/4820366e-4acf-4492-8b8b-2fd4e0b26be2",
            rsa_token.header['jku'])
        self.assertEqual("admin", rsa_token.payload['user'])

        pk = load_pem_private_key(utils.read_pem_file("./keys/pk1.pem"), None,
                                  default_backend())
        pubkey = load_pem_public_key(utils.read_pem_file("./keys/pubkey1.pem"),
                                     default_backend())
        signature = rsa_token.compute_signature(pk)
        self.assertEqual(rsa256_token_signature,
                         utils.force_unicode(signature))
        self.assertTrue(
            rsa_token.verify_signature(pubkey,
                                       utils.base64url_decode(signature)))
        self.assertTrue(
            rsa_token.verify_signature(
                pubkey, utils.base64url_decode(rsa256_token_signature)))
Esempio n. 2
0
    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))
Esempio n. 3
0
    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])
Esempio n. 4
0
 def attack_payload(self, payload_file: str):
     lines = read_file(payload_file, join_lines=False)
     header, payload, signature = TestJWT.split_jwt(self.ser_jwt)
     header = json.loads(utils.base64url_decode(header))
     inj_headers = [inject_in_json(header, line) for line in lines]
     for index, inj_header in zip(range(1, 1 + len(inj_headers)),
                                  inj_headers):
         self.payloads["attack_payload_{}".format(index)] = ".".join(
             [utils.force_unicode(inj_header), payload, signature])
Esempio n. 5
0
def decode(jwt, key='', verify=True):
    try:
        signing_input, crypto_segment = jwt.rsplit('.', 1)
        header_segment, payload_segment = signing_input.split('.', 1)
    except ValueError:
        raise DecodeError("Not enough segments")
    try:
        header = json.loads(base64url_decode(header_segment))
        payload = json.loads(base64url_decode(payload_segment))
        signature = base64url_decode(crypto_segment)
    except (ValueError, TypeError):
        raise DecodeError("Invalid segment encoding")
    if verify:
        try:
            valid = JWS(header, payload).verify(signature, key)
        except KeyError:
            raise DecodeError("Algorithm not supported")
    return payload
Esempio n. 6
0
    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))
Esempio n. 7
0
    def deserialize(ser_token: str):
        """
        Builds a TestJWT from a serialized JWT representation
        :param ser_token: serialized token
        :return: TestJWT instance
        """
        tok1, tok2, sig = TestJWT.split_jwt(ser_token)
        head = utils.base64url_decode(tok1)
        payload = utils.base64url_decode(tok2)
        jwt = TestJWT()
        jwt.original_jwt = ser_token

        # noinspection PyBroadException
        try:
            jwt.header = json.loads(head)
            jwt_payload = json.loads(payload)
            jwt.set_payload(jwt_payload)
        except:
            jwt.set_payload(utils.force_unicode(payload))
        return jwt
Esempio n. 8
0
def parse_and_validate():
    if len(sys.argv) < 2:
        print_help()
    if len(sys.argv) >= 2:
        serial_jwt = sys.argv[1]
        _, _, signature = TestJWT.split_jwt(serial_jwt)
        jwt: TestJWT = TestJWT.deserialize(serial_jwt)
        jwt.show_token()
        if len(sys.argv) == 3:
            params: str = sys.argv[2]
            param_val = get_arg_value(params)
            if param_val is None:
                print_help()
                return
            verified_sig = False
            if params.startswith("-s") and param_val:
                secret = param_val
                verified_sig = jwt.verify_signature(secret, signature)
            elif params.startswith("-p") and param_val:
                key = load_pem_public_key(utils.read_pem_file(param_val),
                                          default_backend())
                verified_sig = jwt.verify_signature(
                    key, utils.base64url_decode(signature))
            elif params.startswith("-jwks") and param_val:
                jwks = json.loads(
                    utils.read_file(param_val,
                                    strip_newline=True,
                                    join_lines=True))
                key = utils.rsa_jwks_to_pubkey(jwks)
                verified_sig = jwt.verify_signature(
                    key, utils.base64url_decode(signature))
            # TODO add support to verify signature if jwk is included in header
            else:
                print_help()
                return
            if verified_sig:
                print("Signature verified")
            else:
                print("Signature verification FAILED !!")
    def from_public_key(cls, public_key):
        """
        Given a URL Safe public key, convert it into a token to validate signatures
        :param public_key: Base64 URL encoded public key
        :return: Token()
        """
        bin_sig = utils.base64url_decode(public_key)
        coordinate_len = len(bin_sig)/2

        bin_x = bin_sig[:coordinate_len]
        bin_y = bin_sig[coordinate_len:]

        x = unpack_bytes(bin_x)
        y = unpack_bytes(bin_y)

        new_token = cls()
        new_token.load_validate(x, y)

        return new_token
Esempio n. 10
0
    def verify(self, payload, signature):
        """
        Verify that the token signed the data
        :type payload: String
        :param payload: message that was signed and needs verified
        :type signature: Base64 URL Safe
        :param signature: Signature that can verify the senders
         identity and payload
        :return:
        """
        raw_sig = utils.base64url_decode(signature)
        sig_r_bin = raw_sig[:len(raw_sig)/2]
        sig_s_bin = raw_sig[len(raw_sig)/2:]

        sig_r = unpack_bytes(sig_r_bin)
        sig_s = unpack_bytes(sig_s_bin)

        sig = encode_dss_signature(sig_r, sig_s)
        signer = self.public_key.verifier(sig,
                                          ec.ECDSA(hashes.SHA256()))
        signer.update(payload)
        signer.verify()