Example #1
0
def break_ecb():
    # Find block size
    pt = b""
    old_l = l = len(encrypt_aes_ecb_same_key(pt))
    while old_l == l:
        pt += b"A"
        l = len(encrypt_aes_ecb_same_key(pt))

    block_size = l - old_l
    print "Block size is {}".format(block_size)

    # Detect mode
    print "Mode is {}".format(crypto.aes_mode_oracle(encrypt_aes_ecb_same_key))

    # Find out the length of the random string
    # -- Keep adding a character until finally the size grows. The blocks at
    #    that point don't need padding, and so the length of the random string
    #    is the length of ct - the random string and the added length
    unknown_len = len(unknown_string)
    old_l = l = len(encrypt_aes_ecb_same_key(b"")) - unknown_len
    while old_l == l:
        pt += b"A"
        l = len(encrypt_aes_ecb_same_key(pt))
    random_len = l - len(pt) - unknown_len - block_size + 2 # +2 to compensate for extra 'A' and longer l

    # Leak out byte by byte
    secret_text = b""  # The secret string so far
    # Pad to multiple of block_size
    unknown_len = unknown_len/block_size*block_size + (block_size if unknown_len % block_size else 0)
    # Pad the uncontrolled random text to a block size
    left_pad_len = random_len/block_size*block_size + (block_size if random_len % block_size else 0)
    left_pad = b"L" * (left_pad_len - random_len)
    total_len = unknown_len + left_pad_len

    # Brute force each byte
    while len(secret_text) < len(unknown_string):
        # We control a 'center' pad. We don't care about the random on the
        # left as long as it ends on a block barrier, so consider it extra padding
        center_pad = b"A" * (unknown_len - len(secret_text) - 1)
        # Encrypt our padding so that the known bytes plus one unknown are in the first chunk
        v = encrypt_aes_ecb_same_key(left_pad + center_pad)
        #import pdb; pdb.set_trace()
        # Now brute force this last byte until the whole ct to that point matches
        for i in range(256):
            ct = encrypt_aes_ecb_same_key(left_pad + center_pad + secret_text + chr(i))
            if ct[0:total_len] == v[0:total_len]:
                secret_text += chr(i)
                break

    print secret_text