Skip to content

Instantly share code, notes, and snippets.

@dzamlo
Created October 13, 2021 17:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dzamlo/d700f811178ad48f57e4d70895b241ba to your computer and use it in GitHub Desktop.
Save dzamlo/d700f811178ad48f57e4d70895b241ba to your computer and use it in GitHub Desktop.
import itertools
import json
import math
import string
############################
encrypted_hex = """
put the encrypted response here
"""
key_len = 16
key_charset = string.ascii_lowercase[:14]
decrypted_charset = string.printable
###########################
key_charset_bytes = [ord(c) for c in key_charset]
decrypted_charset_bytes = [ord(c) for c in decrypted_charset]
def decrypt(key_bytes, encrypted_bytes):
key_len = len(key_bytes)
decrypted = []
for (i, b) in enumerate(encrypted_bytes):
decrypted.append(b ^ key_bytes[i % key_len])
return bytes(decrypted)
def find_candidates_key_bytes(encrypted_bytes, key_offset):
bytes_to_check = encrypted_bytes[key_offset::key_len]
for k in key_charset_bytes:
if all(k ^ b in decrypted_charset_bytes for b in bytes_to_check):
yield k
def is_valid_json(decrypted):
try:
json.loads(decrypted)
except json.JSONDecodeError:
return False
return True
def find_key(encrypted_bytes):
candidates_key_bytes = [
list(find_candidates_key_bytes(encrypted_bytes, i)) for i in range(16)
]
number_of_keys = math.prod(len(l) for l in candidates_key_bytes)
print(f"{number_of_keys} keys to test")
for key in itertools.product(*candidates_key_bytes):
decrypted = decrypt(key, encrypted_bytes)
if is_valid_json(decrypted):
key_ascii = "".join(chr(c) for c in key)
print(f"potential key found: {key_ascii}")
if __name__ == "__main__":
find_key(bytes.fromhex(encrypted_hex))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment