def get_unknown_bytes(oracle): min_ciphertext_length = len(oracle("")) prev = min_ciphertext_length block_size = -1 for i in range(min_ciphertext_length): l = len(oracle("A"*i)) if l != prev: block_size = l - prev break assert block_size != -1 assert detect_ECB_text(oracle("A"*(8*block_size)), block_size) uid = randint(0, 128) plaintext = "" shim_block = "A"*(block_size - 1) block_count = min_ciphertext_length/block_size for i in range(block_count): next_shim = "" for j in range(block_size): oracle_text = oracle(shim_block) target_block = oracle_text[i*block_size:(i+1)*block_size] for k in range(256): guess = shim_block + next_shim + chr(k) result = oracle(guess)[0:block_size] if result == target_block: shim_block = shim_block[1:] next_shim += chr(k) break plaintext += next_shim shim_block = next_shim[1:] return plaintext[:-1]
def get_unknown_bytes_with_rand_prefix(nonfuzzed_oracle): # Generate our obfuscated oracle fuzzed_oracle = lambda s: nonfuzzed_oracle(urandom(randint(0, 512)) + s) block_size = 16 # (For the sake of completeness) verify that the oracle is in ECB mode assert detect_ECB_text(fuzzed_oracle("A"*(8*block_size)), block_size) marker_block = "B"*(block_size - 1) + "C" marker_target = None while True: result = fuzzed_oracle(marker_block*8) blocks = split_into_blocks(result, block_size) for i in range(len(blocks) - 8): if len(set(blocks[i:i+8])) == 1: marker_target = blocks[i] break if marker_target != None: break assert marker_target != None assert len(marker_target) == block_size def defuzzed_oracle(s): # Find the marker target, and truncate it and everything before it. # This removes the random bytes prepended by the fuzzed oracle. while True: result = fuzzed_oracle(marker_block + s) if marker_target in result: target_index = result.index(marker_target) return result[target_index + block_size:] raise AssertionError("defuzzed_oracle went haywire and somehow returned None.") return get_unknown_bytes(defuzzed_oracle)