def main(): inp = bytes(70) data_set = [] for _ in range(10): enc = '' data, answer = encryption_oracle(inp) reps = len(split_blocks(data, 16)) - len(set(split_blocks(data, 16))) if answer == 0: enc = 'ECB' else: enc = 'CBC' data_set.append((enc, reps)) for element in data_set: print(element)
def cbc_decrypt(ciphertext, key, iv=bytes(16)): """ Currently has AES-128 hardcoded default iv is 16 zerobytes """ blocksize = len(iv) pre_plain = decrypt_ecb_aes(ciphertext, key, False) c_blocks = [iv] c_blocks += split_blocks(ciphertext, blocksize) pp_blocks = split_blocks(pre_plain, blocksize) plaintext = b'' for i, block in enumerate(pp_blocks): plaintext += cbc_decrypt_block(c_blocks[i], block) plaintext = pkcs7_depad(plaintext, blocksize) return plaintext
def ctr_transform(plain, key, nonce): plain_blocks = split_blocks(plain, 16) cipher_blocks = [] keystream = ctr_aes128_keystream_gen(key, nonce) for block in plain_blocks: ks_block = next(keystream) cipher_blocks.append(xor_bytes(ks_block, block)) return b''.join(cipher_blocks)
def cbc_padding_oracle(oracle, ciphertext, blocksize, iv=None): if iv is None: iv = bytes(blocksize) c_blocks = tools.split_blocks(ciphertext, blocksize) p_blocks = [] for i, c_block in enumerate(c_blocks): if i == 0: pre = iv else: pre = c_blocks[i-1] p_blocks.append(cbc_po_block(oracle, pre, c_block)) return b''.join(p_blocks)
def remove_pref_blocks(func, inp, pref_length, blocksize): """wrapper takes a func pain --> ciphertext padds the input to fill prefix blocks and strip output return output as if there was no prefix""" padding = bytes(blocksize - pref_length % blocksize) padded_out = func(padding+inp) block_to_remove = pref_length//blocksize if pref_length % blocksize != 0: block_to_remove += 1 stripped_out = tools.split_blocks(padded_out, blocksize)[block_to_remove:] return b''.join(stripped_out)
def main(): blocksize, padding = analyse.test_blocksize(profile_for) print("Blocksize found: ", blocksize) print("Paddingbytes: ", padding) print("ECB detected: ", analyse.test_ecb(profile_for, blocksize)) pref_length = tools.get_pref_len(profile_for, blocksize) print("prefix_length: ", pref_length) print("constructing fake end block") fill = b'A'*(blocksize-(pref_length % blocksize)) fake_end_plain = tools.pkcs7_padding(b'admin', blocksize) target_block = (pref_length//blocksize)+1 end = tools.split_blocks(profile_for(fill+fake_end_plain), blocksize)[target_block] dec_end = dec_profile(end) print("test decoding generated fake end block: ", dec_end) if dec_end == b'admin': print("SUCCESS!") print("generating aligned main cipherblocks") main_fill = b'A'*(padding+len(b"user")) main_blocks = tools.split_blocks(profile_for(main_fill), blocksize)[:-1] main_ciphertext = b''.join(main_blocks) print("constructing payload") payload = main_ciphertext+end print("Testdecoding payload: ", dec_profile(payload))
def cbc_encrypt(plaintext, key, iv=bytes(16)): """ hardcoded to use aes-128, and pkcs7_padding default iv is 16 zerobytes """ try: plaintext = plaintext.encode() except AttributeError: pass blocksize = len(iv) plain_padded = pkcs7_padding(plaintext, blocksize) plain_blocks = split_blocks(plain_padded, blocksize) cipher_blocks = [iv] for block in plain_blocks: cipher_blocks.append(cbc_encrypt_block(cipher_blocks[-1], block, key)) return b''.join(cipher_blocks[1:]) # return ciphertext without IV
def cbc_byteflip(func, target_plain, base_plain, blocksize, prefix_length=0): if max(len(target_plain), len(base_plain)) > blocksize: raise ValueError("Attack does not support targets larger than blocksize") elif len(target_plain) != len(base_plain): raise ValueError("target_plain and base_plain have to be of equal length") offset = 0 if prefix_length % blocksize != 0: offset = blocksize - prefix_length % blocksize padd_start = b'A' * offset + b'A' * blocksize base_cipher_blocks = tools.split_blocks(func(padd_start + base_plain), blocksize) target_index = (prefix_length + offset) // blocksize target_block = base_cipher_blocks[target_index] padd_block = bytes(blocksize - len(target_plain)) base_plain += padd_block target_plain += padd_block # generate modified cipher_block diff = tools.xor_bytes(target_plain, base_plain) new_block = tools.xor_bytes(diff, target_block) mod_cipher_blocks = base_cipher_blocks[:] mod_cipher_blocks[target_index] = new_block return b''.join(mod_cipher_blocks)