Ejemplo n.º 1
0
def break_cbc_using_padding(oracle, cipher, iv):
    cracked = bytearray()
    actual_iv = iv
    for target_start in range(0, len(cipher), 16):
        # this is the intermediate block that comes out of the decryptor
        intermediate = bytearray()
        first_block = bytearray(random_key(16))
        for target_padding_byte in range(1, 17):

            # adjust all solved bytes to match new target padding
            for solved in range(0, len(intermediate)):
                reverse_index = -(solved+1)
                first_block[reverse_index] = intermediate[reverse_index] ^ target_padding_byte

            for b in range(0, 256):
                first_block[-target_padding_byte] = b
                valid = oracle(cipher[target_start : target_start+16], first_block)
                if(valid):
                    # valid padding, b ^ found_padding = real_byte 
                    intermediate.insert(0, target_padding_byte ^ b)
                    break
                elif(b == 255):
                    raise Exception("couldn't find valid padding byte")

        cracked.extend(xortools.xor_bytes(bytes(intermediate), actual_iv))
        actual_iv = cipher[target_start : target_start + 16]
    return strip_valid_padding(bytes(cracked))
Ejemplo n.º 2
0
def do_ctr(input, key, nonce):
    aes = AES.new(key)
    input_chunks = chunks(input, 16)
    encrypted = b''
    count = bytearray(bytes(8))
    for input_chunk in input_chunks:
        keystream = nonce + bytes(count)
        encrypted_keystream = aes.encrypt(keystream)
        encrypted += xortools.xor_bytes(encrypted_keystream[0 : len(input_chunk)], input_chunk)
        count[0] += 1
    return encrypted
Ejemplo n.º 3
0
def decrypt_cbc(input, key, iv, strip=True):
    blocksize = 16
    last = iv
    output = bytearray()
    blocks = chunks(input, blocksize)
    for block in blocks:
        decrypted = decrypt_ecb(bytes(block), key)
        combined = xortools.xor_bytes(last, decrypted)
        output.extend(combined)
        last = block

    return strip_valid_padding(output) if strip else output
Ejemplo n.º 4
0
def encrypt_cbc(input, key, iv):
    blocksize = 16
    last = iv
    output = bytearray()
    input = padded(input, blocksize)
    blocks = chunks(input, blocksize)
    for block in blocks:
        combined = xortools.xor_bytes(last, block)
        encrypted = encrypt_ecb(combined, key)
        output.extend(encrypted)
        last = encrypted
    return output
Ejemplo n.º 5
0
    def test_challenge_2(self):
        """ Challenge 2: XOR two strings """

        input_one = '1c0111001f010100061a024b53535009181c'
        input_two = '686974207468652062756c6c277320657965'
        expected_out = '746865206b696420646f6e277420706c6179'

        bytes_one = conv.hex_to_bytes(input_one)
        bytes_two = conv.hex_to_bytes(input_two)
        expected_bytes_out = conv.hex_to_bytes(expected_out)

        self.assertEqual(xortools.xor_bytes(bytes_one, bytes_two), expected_bytes_out)
Ejemplo n.º 6
0
    def test_challenge_19(self):
        """ Challenge 19: Break fixed-nonce CTR """

        key = aestools.random_key(16)
        nonce = bytes(8)
        input_file = open('files/19.txt', 'r')
        lines = [conv.base_64_to_bytes(line.rstrip()) for line in input_file]
        input_file.close()
        encrypted_lines = [aestools.do_ctr(line, key, nonce) for line in lines]

        index = 0
        probable_bytes = bytearray()
        while(True):
            rotated = "".join([chr(line[index]) if index < len(line) else '' for line in encrypted_lines])
            b, all, score = xortools.solve_xor_block(bytes(rotated, 'utf-8'))
            probable_bytes.append(b)
            index += 1
            if len(rotated) == 0: break

        for line in encrypted_lines:
            close = xortools.xor_bytes(line, bytes(probable_bytes[0 : len(line)]))
            readable = " ".join([chr(b) if b in range(32, 127) else 'X' for b in close])