def oracle(message): prepend = bytes( [random.randint(0, 255) for i in range(random.randint(5, 10))]) append = bytes( [random.randint(0, 255) for i in range(random.randint(5, 10))]) plaintext = prepend + message + append key = bytes([random.randint(0, 255) for i in range(16)]) ecb_or_cbc = random.randint(0, 1) if (ecb_or_cbc == 0): #ebc pkcs7.PKCS7_pad(plaintext, 16) ciphertext = AES.new(key, AES.MODE_ECB).encrypt( pkcs7.PKCS7_pad(plaintext, 16)) else: #cbc iv = bytes([random.randint(0, 255) for i in range(16)]) ciphertext = cbc.encrypt_cbc_with_ecb(pkcs7.PKCS7_pad(plaintext, 16), key, iv, 16) return { 'ciphertext': ciphertext, 'mode': ecb_or_cbc } #we need a way to check our guesses
# checks if the decrypted block contains padding information or bytes used for padding # in which case we need to make an additional attempt if (len(last_bytes) > 1): for byte in last_bytes: modified_c1s = [(generate_modified_c1( ciphertext_blocks[block_index], i, len(plaintext_block) + 2, bytes([byte]) + plaintext_block), byte) for i in range(256)] for c1 in modified_c1s: # should only enter once since we resolve ambiguities here if (oracle(ciphertext_blocks[block_index + 1], c1[0])): last_byte = c1[1] break plaintext_block = bytes([last_byte]) + plaintext_block else: plaintext_block = bytes([last_bytes[0]]) + plaintext_block plaintext += plaintext_block return plaintext if __name__ == "__main__": to_encrypt = pkcs7.PKCS7_pad( messages[random.randint(0, len(messages) - 1)], 16) encrypted = cbc_encrypt(to_encrypt) decrypted_string = get_plaintext(encrypted['ciphertext'], encrypted['iv'], padding_oracle) print(decrypted_string) assert (decrypted_string == to_encrypt)
def cbc_encrypt(message): plaintext = (b'comment1=cooking%20MCs;userdata=' + message + b'comment2=%20like%20a%20pound%20of%20bacon').\ replace(b';', b'%3b').replace(b'=', b'%3d') return CBC.encrypt_cbc_with_ecb(pkcs7.PKCS7_pad(plaintext, 16), key, iv, 16)
def oracle(message): #modify oracle to this form: AES-128-ECB(random-prefix || attacker-controlled || target-bytes, random-key) return AES.new(key, AES.MODE_ECB).encrypt( pkcs7.PKCS7_pad( prefix + message + binascii.a2b_base64(string_to_decrypt), 16))
def profile_for(email): if(b'&' in email or b'=' in email): raise ValueError("Failed To Create Email") return AES.new(key, AES.MODE_ECB).encrypt(pkcs7.PKCS7_pad(b'email=' + email + b'&uid=10&role=user', 16))
def oracle(message): return AES.new(key, AES.MODE_ECB).encrypt( pkcs7.PKCS7_pad(message + binascii.a2b_base64(string_to_decrypt), 16))