def challenge34(): p = 197 g = 3 dh1 = DiffieHellman() dh2 = DiffieHellman() dh1._p = dh2._p = p dh1._g = dh2._g = g A = dh1.gen_pub() B = dh2.gen_pub() #dh2.gen_secret(A) dh2.gen_secret(p) #dh1.gen_secret(B) dh1.gen_secret(p) message = b'hello, MITM' key1 = hashlib.sha1(dh1.secret.to_bytes(64, 'big')).digest()[:16] iv1 = os.urandom(16) ct1 = set2.aes_cbc_encrypt(message, key1, iv1) key2 = hashlib.sha1(dh2.secret.to_bytes(64, 'big')).digest()[:16] iv2 = os.urandom(16) message2 = set2.aes_cbc_decrypt(ct1, key2, iv1) ct2 = set2.aes_cbc_encrypt(message2, key2, iv2) message3 = set2.aes_cbc_decrypt(ct2, key1, iv2) assert message == message3 key3 = hashlib.sha1((0).to_bytes(64, 'big')).digest()[:16] message4 = set2.aes_cbc_decrypt(ct1, key3, iv1) assert message == message4
def challenge35(): p = 197 g = 3 dh1 = DiffieHellman() dh2 = DiffieHellman() for fg in [1, p, p - 1]: dh1._p = dh2._p = p dh1._g = dh2._g = fg A = dh1.gen_pub() B = dh2.gen_pub() dh2.gen_secret(A) dh1.gen_secret(B) message = b'hello, MITM' key1 = hashlib.sha1(dh1.secret.to_bytes(64, 'big')).digest()[:16] iv1 = os.urandom(16) ct1 = set2.aes_cbc_encrypt(message, key1, iv1) key2 = hashlib.sha1(dh2.secret.to_bytes(64, 'big')).digest()[:16] iv2 = os.urandom(16) message2 = set2.aes_cbc_decrypt(ct1, key2, iv1) ct2 = set2.aes_cbc_encrypt(message2, key2, iv2) message3 = set2.aes_cbc_decrypt(ct2, key1, iv2) assert message == message3 if fg == 1: s = 1 elif fg == p: s = 0 else: if A == p - 1 and B == p - 1: s = p - 1 else: s = 1 key3 = hashlib.sha1((s).to_bytes(64, 'big')).digest()[:16] message4 = set2.aes_cbc_decrypt(ct1, key3, iv1) assert message == message4
def test_challenge10(): text = b'We choose to go to the moon.' key = b'YELLOW SUBMARINE' iv = os.urandom(len(key)) ciphertext = set2.aes_cbc_encrypt(text, key, iv) assert text == set2.aes_cbc_decrypt(ciphertext, key, iv) with open('10.txt') as f: b64string = f.read() ciphertext = base64.b64decode(b64string.encode()) plaintext = set2.aes_cbc_decrypt(ciphertext, key, bytes(len(key))) assert plaintext.startswith(b"I'm back and I'm ringin' the bell \n") and plaintext.endswith(b'funky music \n')
def challenge_27_detect_admin(cipher): decrypted = aes_cbc_decrypt(cipher, challenge_27_aes_key, iv=challenge_27_aes_key) for decrypted_byte in decrypted: if decrypted_byte > 127: raise RuntimeError return decrypted.count(b";admin=true") > 0
def challenge27_isadmin(ciphertext): plaintext = set2.aes_cbc_decrypt(ciphertext, constants.key, constants.key, unpad=False) for byte in plaintext: if byte >= 128: raise AsciiError(plaintext) return b';admin=true;' in plaintext
def challenge17_decrypt(ciphertext, iv): plaintext = set2.aes_cbc_decrypt(ciphertext, constants.key, iv, unpad=False) try: set2.pkcs7_unpad(plaintext, 16, True) return True except set2.PaddingError: pass return False
def consume_cookie(cipher, iv=None): ''' This function approximates AES-CBC encryption on a webserver. It models the server's consumption of an encrypted session token, as if it were a cookie. Note, it simply checks to see if the data it was given CAN be a valid cookie, it does not guarantee that the data actually CORRESPONDS to a cookie that the server has given out. ''' decrypted = aes_cbc_decrypt(cipher, GLOBAL_RANDOM_KEY, iv=iv) try: validate_pkcs7(decrypted) return True except ValueError: return False
def decryption_oracle(ciphertext, key, blocksize=16): iv = ciphertext[:blocksize] return unpadpkcs7(aes_cbc_decrypt(ciphertext[blocksize:], key, iv))
def cbc_padding_oracle(ciphertext, key): blocksize = len(key) iv = ciphertext[:blocksize] return validatepkcs7(aes_cbc_decrypt(ciphertext[blocksize:], key, iv))
def decryption_oracle(ciphertext, key, blocksize=16): iv = key blocks = aes_cbc_decrypt(ciphertext, key, iv) if not all(map(lambda x: x in range(0, 128), blocks)): raise Not7BitAscii(blocks) return unpadpkcs7(blocks)