def encrypt(self, user_bytes): user_string = decode(user_bytes) clean_user_string = user_string.replace(";", '";"').replace("=", '"="') byte_string = b"".join( [self.prefix, encode(clean_user_string), self.suffix]) data = bo.pad(16, byte_string) return AESCBC(self.iv, self.key).encrypt(data)
def challenge_10(): print(f"\n-- Challenge 10 - Implement CBC mode --") data_p = bo.pad(16, b"This is a secret message! TOP SECRET") key = b"PASSWORDPASSWORD" iv = b"1122334455667788" ECB_1 = ocl.AESECB(key) CBC_1 = ocl.AESCBC(iv, key) ECB_ciphertext = ECB_1.encrypt(data_p) ECB_plaintext = bo.depad(ECB_1.decrypt(ECB_ciphertext)) CBC_ciphertext = CBC_1.encrypt(data_p) CBC_plaintext = bo.depad(CBC_1.decrypt(CBC_ciphertext)) print(f"Padded Secret Message : {data_p}") print(f"Key : {key}") print(f"ECB encrypted message : {ECB_ciphertext}") print(f"ECB decrypted message : {ECB_plaintext}") print(f"iv : {iv}") print(f"CBC encrypted message : {CBC_ciphertext}") print(f"CBC decrypted message : {CBC_plaintext}") print("----- Part 2 ------") data = b64decode(ut.import_data("data_S2C10.txt")) key = b"YELLOW SUBMARINE" iv = bytes([0]) * 16 CBC_2 = ocl.AESCBC(iv, key) decrypted = decode(bo.depad(CBC_2.decrypt(data))) print(f"CBC decrypted message : \n{decrypted[0:90]}...")
def challenge_9(): print(f"\n-- Challenge 9 - Implement PKCS#7 padding --") data = encode("YELLOW SUBMARINE") size = 20 print(f"{data} padded to {size} bytes using PKCS#7 : " f"{bo.pad(size, data)}") return bo.pad(size, data)
def encrypt(self, data): data = secrets.token_bytes( secrets.randbelow(5)) + data + secrets.token_bytes( secrets.randbelow(5)) data_padded = bo.pad(16, data) if self.mode == "ECB": result = AESECB(self.key).encrypt(data_padded) else: result = AESCBC(self.iv, self.key).encrypt(data_padded) return result
def challenge_13(): print(f"\n-- Challenge 13 - ECB cut-and-paste --") print(f"-- Part 1 --") text = """foo=bar&baz=qux&zap=zazzle""" email = "*****@*****.**" parsed = ocl.profile_parse(email) print(f"Example string : {text}") print(f"Unpacked profile : {ocl.profile_unpack(encode(text))}") print(f"Example Email : {email}") print(f"Parsed profile : {parsed}") print(f"Unpacked profile : {ocl.profile_unpack(parsed)}") print(f"-- Part 2 --") base_email = "*****@*****.**" base_encryption = ocl.profile_create(base_email) base_encryption_len = len(base_encryption) base_decryption = ocl.profile_decrypt(base_encryption) print(f"Base email : {base_email}") print(f"Encrypted profile : {base_encryption}") print(f"Encrypted size : {base_encryption_len}") print(f"Decrypted data : {base_decryption}") # Create an email that creates a whole new block in output. end_align_email = base_email end_align_encryption = base_encryption while len(end_align_encryption) == base_encryption_len: end_align_email = "a" + end_align_email end_align_encryption = ocl.profile_create(end_align_email) end_align_encryption_len = len(end_align_encryption) print(f"End aligning email : {end_align_email}") print(f"Encrypted profile : {end_align_encryption}") print(f"Encrypted size : {end_align_encryption_len}") # Add bytes to push unwanted data from encryption into end # block and crop useful blocks. bytes_to_remove = len(b"user") crop_email = ("b" * bytes_to_remove) + end_align_email crop = ocl.profile_create(crop_email)[0:48] decryption = ocl.profile_decrypt(crop) print(f"bytes to push into new block : {bytes_to_remove}") print(f"Crop aligning email : {crop_email}") print(f"Encrypted profile crop : {crop}") print(f"Crop size : {len(crop)}") print(f"Decrypted crop : {decryption}") # Create an email that shows its position in the encryption. position_email = base_email # Look for two identical blocks in encryption. while not bo.ECB_mode_check(ocl.profile_create(position_email)): position_email = "c" + position_email print(f"Position finding email : {position_email}") # Find position at which duplicated block starts changing. position = 0 while bo.ECB_mode_check(ocl.profile_create(position_email)): position_email_list = list(position_email) position_email_list[position] = "d" position_email = "".join(position_email_list) position += 1 position -= 1 print(f"Position finding email : {position_email}") print(f"Position of block start : {position}") bytes_to_add = position - len(base_email) if bytes_to_add < 0: bytes_to_add += 16 block_end_email = ("e" * bytes_to_add) + base_email print(f"Bytes to add to email : {bytes_to_add}") print(f"Email ending block : {block_end_email}") # Craft new ending for encrypted data. new_end = decode(bo.pad(16, b"admin")) new_end_encryption_email = block_end_email + new_end cut = ocl.profile_create(new_end_encryption_email)[32:48] decrypted_cut = ocl.profile_decrypt(cut) print(f"new end encrypting email : {new_end_encryption_email}") print(f"new ending encryption : {cut}") print(f"new ending decrypted : {decrypted_cut}") attacker_encrypted_profile = crop + cut attacker_decrypted_profile = ocl.profile_decrypt( attacker_encrypted_profile) attacker_profile = ocl.profile_unpack( bo.depad(attacker_decrypted_profile)) print(f"Attacker encrypted profile : {attacker_encrypted_profile}") print(f"Attacker decrypted profile : {attacker_decrypted_profile}") print(f"Attacker profile : {attacker_profile}") return attacker_profile
def encrypt(self, prepend): data = bo.pad(16, prepend + self.secret) return AESECB(self.key).encrypt(data)
def profile_create(email): data = profile_parse(email) padded_data = bo.pad(16, data) return AESECB(b"PASSWORDPASSWORD").encrypt(padded_data)
def reveal(self): return bo.pad(16, self.data)
def encrypt(self): data = bo.pad(16, self.data) ciphertext = AESCBC(self.iv, self.key).encrypt(data) return ciphertext, self.iv
def test_pad(self): self.assertEqual(bo.pad(3, b""), b"\x03\x03\x03") self.assertEqual(bo.pad(2, b"test"), b"test\x02\x02") self.assertEqual(bo.pad(4, b"test"), b"test\x04\x04\x04\x04") self.assertEqual(bo.pad(10, b"test"), b"test\x06\x06\x06\x06\x06\x06")