Ejemplo n.º 1
0
def challenge_26_admin_check(ciphertext, key, nonce):
    # Obtain plaintext
    plaintext = set2.pkcs7_remove_padding(
        set3.decrypt_aes_ctr(ciphertext, key, nonce))
    # Parse text as object
    items = {x: y for x, y in [z.split(b'=') for z in plaintext.split(b';')]}
    # Check whether 'admin' property is in object, and is set to 'true'
    return b'admin' in items and items[b'admin'] == b'true'
Ejemplo n.º 2
0
def decrypt_aes_cbc_2(text, key, iv):
    # Create blocks of the key's length each
    blocks = [text[i:i + len(key)] for i in range(0, len(text), len(key))]
    results = []
    for _, block in enumerate(blocks):
        # Decrypt the current block with the given key
        deciphered_block = set1.decrypt_aes_ecb(block, key)
        # XOR the deciphered block with the IV
        xored_deciphered_block = set1.XOR(deciphered_block, iv)
        # Decode the result as a string, and add it to the result set
        results.extend(xored_deciphered_block)
        # Set the IV of the next block as the current block's ciphertext
        iv = block
    return set2.pkcs7_remove_padding(bytes(results))
Ejemplo n.º 3
0
def challenge_25():
    key = set2.random_bytes(16)
    nonce = random.randrange(1, 10**10)
    # Get plaintext
    with open('inputs/25.txt') as file:
        contents = base64.b64decode(file.read())
    plaintext = set2.pkcs7_remove_padding(
        set1.decrypt_aes_ecb(contents, 'YELLOW SUBMARINE'))
    # Generate ciphertext
    ciphertext = set3.encrypt_aes_ctr(plaintext, key, nonce)

    # Create vulnerable function
    def vulnerable_ctr_stream_edit_function(ciphertext, offset, newtext):
        return edit_ctr_stream(ciphertext, key, nonce, offset, newtext)

    # Find the plaintext using the above function
    obtained_plaintext = find_ctr_plaintext(
        ciphertext, vulnerable_ctr_stream_edit_function)
    # Verify found plaintext matches with the original plaintext
    assert_true(obtained_plaintext == plaintext)
Ejemplo n.º 4
0
    def decrypt_message(self):
        # We know s = 0, because Alice thinks B = p = 0 (mod p), and Bob thinks A = p = 0 (mod p)
        key_candidates = []
        if self.g_prime == 1:
            # A=g^a, B=g'^b=1
            # s_a=B^a=1^a=1, s_b=A^b=?
            key_candidates = [1]
        if self.g_prime == self.p:
            # A=g^a, B=g'^b=0
            # s_a=0^a=0^a=0, s_b=A^b=?
            key_candidates = [0]
        if self.g_prime == self.p-1:
            # A=g^a, B=g'^b=(-1)^b={either 1 or -1}
            # s_a=B^a={either 1 or -1}, s_b=A^b=?
            key_candidates = [1, -1]

        for key in key_candidates:
            try:
                return set2.pkcs7_remove_padding(set2.decrypt_aes_cbc(text=self.msg, key=hashlib.sha1(long_to_bytes(key)).digest()[0:16], iv=self.iv, unpad=False))
            except ValueError:
                continue
        return None #raise ValueError("Decryption failed (keys tried: {})".format(key_candidates))
Ejemplo n.º 5
0
def aes_oracle_attack(oracle, ciphertext, iv):
    # Determine number of blocks
    number_of_blocks = len(ciphertext) // 16
    # Prepend IV to given ciphertext (as it is the 'previous' block for the first cipher text block)
    ciphertext = bytearray(iv) + bytearray(ciphertext)
    #Initialise result byte array
    result = bytearray()
    # Iterate over ciphertext blocks
    for block in range(number_of_blocks):
        block_result = bytearray()
        for padding_value in range(1, 17):
            # Select window, i.e. block being investigated plus the previous block
            ct = ciphertext[block * 16:(block + 2) * 16]
            # Set the bytes that have been recovered already
            # by XORing the ciphertext value with the found plaintext and the padding value for this round
            for i, plaintext in enumerate(block_result, start=1):
                ct[16 - i] = padding_value ^ ct[16 - i] ^ plaintext
            for guessed_value in range(256):
                # Modify the ciphertext of the previous block to the guesesed value
                ct[16 - padding_value] = guessed_value
                # Test if padding is correct
                if oracle(bytes(ct)):
                    # If so, find plaintext character by XORing the guessed value with the value it must have resulted in (=`padding_value`) XORed with the original ciphertext character
                    found_plaintext = padding_value ^ ciphertext[
                        (block * 16) + (16 - padding_value)] ^ guessed_value
                    if len(block_result) != padding_value:
                        # Append found plaintext character to block_result
                        block_result.append(found_plaintext)
                        if found_plaintext != 1: break
                    else:
                        if found_plaintext > block_result[-1]:
                            block_result[-1] = found_plaintext
        # Prepend our block result to the overall result
        result = block_result + result
    # Reverse the byte order, unpad it and return it as the found plaintext
    result.reverse()
    result = set2.pkcs7_remove_padding(result)
    return result