def bitflip_attack(oracle): target = b';admin=true;c=mo' ct = oracle.encrypt(b'') ct_blocks = [ct[i:i + BSIZE] for i in range(0, len(ct), BSIZE)] c1 = ct_blocks[1] m2 = SUFFIX[:BSIZE] pad = bytes_xor(c1, m2) bait = bytes_xor(target, pad) payload = b''.join([ct_blocks[0], bait] + ct_blocks[2:]) return oracle.decrypt(payload)
def _keystream_xor(data, key, nonce): res = b'' for pad, chunk in zip( _keystream(key, nonce), [data[i:i + BSIZE] for i in range(0, len(data), BSIZE)]): res += bytes_xor(chunk, pad) return res
def po_attack(oracle): token, iv = oracle.gen_token() tblocks = [token[i:i + BSIZE] for i in range(0, len(token), BSIZE)] prev, curr_block, res = iv, b'', b'' for block in tblocks: for i in range(1, BSIZE + 1): prefix = b'\x00' * (BSIZE - i) suffix = bytes_xor(curr_block, bytes([i]) * (i - 1)) for j in range(1 if i == 1 else 0, 256): mask = prefix + bytes([j]) + suffix bait = bytes_xor(prev, mask) if oracle.verify_tocken(bait + block): curr_block = bytes([i ^ j]) + curr_block break res += curr_block curr_block = b'' prev = block return pkcs7_trim(res)
def decrypt_file(fname): with open(fname) as f: s = b64decode(f.read()) ksize = guess_keysize(s) chunks = [s[i:i + ksize] for i in range(0, len(s), ksize)] tchunks = list(map(bytes, zip_longest(*chunks, fillvalue=0))) key = [] for chunk in tchunks: key.append(guess_key(chunk)[1]) print(bytes_xor(s, bytes(key)).decode('utf-8'))
def string_englishness(s): bs = bytes.fromhex(s) best_val, max_eng = '', 0 for i in range(128): try: val = bytes_xor(bs, bytes([i])).decode('utf-8') eng = englishness(val) if max_eng < eng: best_val, max_eng = val, eng except: continue return (max_eng, best_val)
def break_mtp(s): bs = bytes.fromhex(s) variants = [bytes_xor(bs, bytes([i])).decode('utf-8') for i in range(128)] return max(variants, key=englishness)
def guess_key(bs): variants = [] for i in range(128): variants.append((bytes_xor(bs, bytes([i])).decode('utf-8'), i)) return max(variants, key=lambda x: englishness(x[0]))
def hamming_dist(b1, b2): """Number of bits in which two byte strings differ""" return hamming_weight(bytes_xor(b1, b2))
def aes_cbc_decrypt(ctext, key, iv): res, current = b'', iv for c in [ctext[i:i + BLK_SIZE] for i in range(0, len(ctext), BLK_SIZE)]: res += bytes_xor(_aes_ecb_decrypt(c, key), current) current = c return pkcs7_trim(res)
def aes_cbc_encrypt(ptext, key, iv): res, current, padded = b'', iv, pkcs7_pad(ptext, BLK_SIZE) for p in [padded[i:i + BLK_SIZE] for i in range(0, len(padded), BLK_SIZE)]: current = _aes_ecb_encrypt(bytes_xor(current, p), key) res += current return res