Example #1
0
def byte_ecb_decrypt_hard():
    output_dict = {}
    unknown = b''
    while unknown == b'' or unknown[-1] != 1:
        pre, block_num = prepend_hard(unknown)
        for i in range(128):
            single_chr = bytes(chr(i), 'ascii')
            pt = pre + unknown + single_chr
            ct = list(set1_ch6.chunks(byte_ecb_encrypt_hard(pt, key), block_size))[block_num]
            output_dict[ct] = single_chr
        single_block = list(set1_ch6.chunks(byte_ecb_encrypt_hard(pre, key), block_size))
        unknown += output_dict[single_block[block_num]]
    return unknown[:-1]
Example #2
0
def byte_ecb_decrypt():
    output_dict = {} # dictionary holding blocks with shortened byte and character
    unknown = b'' # uncovered secret string

    while unknown == b'' or unknown[-1] != 1:
        pre, block_num = prepend(unknown)
        for i in range(128): # every possible ascii character
            single_chr = bytes(chr(i), 'ascii')
            pt = pre + unknown + single_chr
            ct = list(set1_ch6.chunks(byte_ecb_encrypt(pt, key), block_size))[block_num]
            output_dict[ct] = single_chr # find matching chunk
        single_block = list(set1_ch6.chunks(byte_ecb_encrypt(pre, key), block_size))
        unknown += output_dict[single_block[block_num]]

    return unknown[:-1]
Example #3
0
def modify_ciphertext(encrypted):
    blocks = list(set1_ch6.chunks(encrypted, 16))
    prev_block = list(blocks[1])
    prev_block[4] ^= 1  # bit flip to make ';'
    prev_block[10] ^= 1  # bit flip to make '='
    blocks[1] = bytes(prev_block)
    encrypted2 = b''.join(blocks)
    return encrypted2
Example #4
0
def detect_prefix_len():
    counter = 0
    cipher = byte_ecb_encrypt_hard(b'A' * (counter + 32), key)
    blocks = list(set1_ch6.chunks(cipher, 16))
    init_repeat = repeats = len(blocks) - len(set(blocks))
    # increment num A's until there are duplicate ciphertext blocks
    while (init_repeat == repeats):
        counter += 1
        cipher = byte_ecb_encrypt_hard(b'A' * (counter + 32), key)
        blocks = list(set1_ch6.chunks(cipher, 16))
        repeats = len(blocks) - len(set(blocks))
    # find which blocks are repeated
    repeat_block = 0
    while repeat_block < len(blocks)-1 and blocks[repeat_block] != blocks[repeat_block+1]:
        repeat_block += 1
    # return number of extra A's, and which block is repeated
    return counter, repeat_block
Example #5
0
def detect_ECB(filename):
    unique = []
    content = []
    with open(filename, "rb") as file:
        for line in file:
            content.append(line)
            chunked = list(set1_ch6.chunks(line, 16))
            unique.append(len(Counter(chunked)))  # number of unique chunks
    AES_encrypted = np.argmin(unique)
    return AES_encrypted, content[AES_encrypted]
Example #6
0
def cbc_encrypt(key, plaintext, iv):
    plaintext = set2_ch9.padding(plaintext, 16)
    blocks = list(set1_ch6.chunks(plaintext, 16))
    prev_encrypt = iv
    ciphertext = []

    for b in blocks:
        xored = set1_ch2.xor(b, prev_encrypt)
        prev_encrypt = set1_ch7.encrypt(key, xored)
        ciphertext.append(prev_encrypt)

    return b"".join(ciphertext)
Example #7
0
def cbc_decrypt_wo_unpad(key, ciphertext, iv):
    blocks = list(set1_ch6.chunks(ciphertext, 16))
    prev_block = iv
    plaintext = []

    for b in blocks:
        decrypted = set1_ch7.decrypt(key, b)
        plaintext.append(set1_ch2.xor(decrypted, prev_block))
        prev_block = b

    joined = b"".join(plaintext)

    return joined
Example #8
0
def exploit_cbc_oracle(iv, ciphertext):
    blocks = [iv] + list(set1_ch6.chunks(ciphertext, 16))
    message = b'' # decrypted message we are uncovering
    # decrypt by block
    for b_num in range(len(blocks)-1):
        guessed = bytearray([0] * 16) # guessed characters
        # start from end of block
        for b in range(15, -1, -1):
            padding = bytearray([0] * 16)
            padding[b:16] = [16-b] * (16-b)
            # xor prev block, padding block, and guessed block
            modified = set1_ch2.xor(set1_ch2.xor(blocks[b_num], padding), guessed)
            # try every possible character until padding is valid
            for i in range(256):
                r = bytearray([0] * 16)
                r[b] = i
                xored = set1_ch2.xor(modified,r)
                if padding_oracle(xored + blocks[b_num+1]):
                    if not (16-b == 1 and i == 1): # check special case of actual padding
                        guessed[b] = i
        message += codecs.decode(guessed, 'base64')
    return message
Example #9
0
def detect_cipher(ciphertext):
    blocks = list(set1_ch6.chunks(ciphertext, 16))
    return "CBC" if len(set(blocks)) == len(blocks) else "EBC"