def func1(rand_key, rand_iv, userdata):
    plainbuf = generate_str(userdata)
    plainbuf_padded = challenge9.pkcs7_pad(16, plainbuf)

    encbuf = challenge10.encrypt_aes_128_cbc(rand_key, rand_iv, plainbuf_padded)

    return encbuf
def aes_cbc_encrypt(k, pt, iv):
    """
    Encrypts a message using AES in CBC mode. Pads as necessary using PKCS#7.

    @param k [str]: ASCII key
    @param pt [str]: ASCII PT string
    @param iv [str]: Initialization vector
    @returns [str]: ASCII CT string
    """
    def ecb_encrypt(k, pt):
        """
        Encrypts a message using AES in ECB mode (assume the input is padded to
        the block size).
        """
        cipher = Cipher(algorithms.AES(k),
                        modes.ECB(),
                        backend=default_backend())
        encryptor = cipher.encryptor()
        return encryptor.update(pt) + encryptor.finalize()

    padded_pt = pkcs7_pad(pt, len(k))
    pt_list = [
        padded_pt[i:i + len(k)] for i in range(0, len(padded_pt), len(k))
    ]
    ct_list = [iv]
    for i in range(len(pt_list)):
        ct_list.append(ecb_encrypt(k, xorstr(ct_list[-1], pt_list[i])))
    return ''.join(ct_list[1:])  # Remove the IV
def encryption_oracle(random_prefix, attacker_controlled, target_bytes, random_key):
    plainbuf = random_prefix + attacker_controlled + target_bytes
    padded_plainbuf = challenge9.pkcs7_pad(16, plainbuf)

    encbuf = challenge7.encrypt_aes_128_ecb(random_key, padded_plainbuf)

    return encbuf
Exemple #4
0
def f(x):
    if type(x) == str:
        x = bytearray(x, 'utf-8')
    unknown_str_b64 = "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkgaGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBqdXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUgYnkK"
    unknown_str = b64_to_bytes(unknown_str_b64)
    new_pt = pkcs7_pad(x + unknown_str, BLK_SZ)
    return encrypt_aes_ecb(new_pt, KEY)
    def __profile_encrypt(self, username):
        """
        :return: encrypted profile to send out to client
        """
        prof_str = self.__profile_for(username.decode())
        profile = challenge9.pkcs7_pad(prof_str.encode("utf-8"), 16)

        ctext = self.__cipher.encrypt(profile)
        return ctext
def aes_encryption_oracle(text, key):
    # Given in the challenge
    secret_string = base64.b64decode(
        b'Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg'
        b'aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq'
        b'dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg'
        b'YnkK')

    cipher = AES.new(key, AES.MODE_ECB)
    return cipher.encrypt(pkcs7_pad(text + secret_string, 16))
def aes_ecb_encrypt(k, pt):
    """
    Encrypts a message using AES in ECB mode. Pads as necessary using PKCS#7.

    @param k [str]: key
    @param pt [str]: PT (ASCII string)
    @returns [str]: CT (ASCII string)
    """

    padded_pt = pkcs7_pad(pt, len(k))
    cipher = Cipher(algorithms.AES(k), modes.ECB(), backend=default_backend())
    encryptor = cipher.encryptor()
    return encryptor.update(padded_pt) + encryptor.finalize()
    def encrypt(self, plaintext):
        """
        Create URL string, adding prefix, postfix comments
        :return: encrypted URL result.
        """
        # prevent user from creating a ;admin=true; string
        plaintext.replace(b";", b"")
        plaintext.replace(b"=", b"")
        plaintext.replace(b"&", b"")
        text = self._prefix + plaintext + self._postfix

        #print(text)
        #print(pkcs7_pad(text, 16))
        return self._cipher.encrypt(pkcs7_pad(text, 16))
Exemple #9
0
def encrypt():
    """
    provide encrypted phrase to client via JSON
    """
    token = random.choice(tokens)
    IV = os.urandom(16)
    global KEY
    KEY = os.urandom(16)
    cipher = AES.new(KEY, AES.MODE_CBC, IV)
    token = challenge9.pkcs7_pad(token, 16)

    ciphertext = cipher.encrypt(token)

    data, iv = base64.b64encode(ciphertext), base64.b64encode(IV)
    return json.dumps([{"token": data.decode()}, {"IV": iv.decode()}])
Exemple #10
0
    def encrypt(self, text):
        ciphertext = []
        plaintext = [
            text[i:i + self.__bsize] for i in range(0, len(text), self.__bsize)
        ]

        if len(plaintext[0]) != self.__bsize:
            plaintext[0] = pkcs7_pad(plaintext[0], self.__bsize)

        block = xor(plaintext[0], self.__IV)
        ciphertext.append(self.__cipher.encrypt(block))

        for p in plaintext[1:]:
            if len(p) != self.__bsize:
                p = pkcs7_pad(p, self.__bsize)

            block = xor(p, ciphertext[-1])
            ciphertext.append(self.__cipher.encrypt(block))

        output = b""
        for c in ciphertext:
            output += c

        return output
def encryption_oracle(input):
    prefix = bytes(urandom(randint(5, 10)))
    suffix = bytes(urandom(randint(5, 10)))
    to_encrypt = pkcs7_pad(prefix + input + suffix, 16)
    random_aes_key = urandom(16)

    if (choice([True, False])):
        cipher = AES.new(random_aes_key, AES.MODE_ECB)
        aes_mode = 'ECB'
    else:
        iv = urandom(16)
        cipher = AES.new(random_aes_key, AES.MODE_CBC, iv)
        aes_mode = 'CBC'

    ciphertext = cipher.encrypt(to_encrypt)
    return ciphertext, aes_mode
Exemple #12
0
def f1(s):
    # quote out ; and = in s
    s = s.replace(';', '";"')
    s = s.replace('=', '"="')

    res = PREPEND + s + APPEND

    # pad
    res_padded = pkcs7_pad(res, BLK_SZ)

    # encrypt under random AES key
    k = gen_aes_key()
    iv = secrets.token_bytes(BLK_SZ)

    res_enc = aes_cbc_encrypt(res_padded, k, iv)

    return k, res_enc, iv
def attacker():
    # generate input such that last block contains only user
    email = "A" * 13
    victim = profile_for(email)
    assert len(profile_for(email[5:])) < len(victim)

    target_block = pkcs7_pad("admin", BLK_SZ)

    # spray email=\x00...|admin__pad__|....
    email_spray = bytearray([0 for _ in range(10)]) + target_block
    evil = profile_for(email_spray.decode('utf-8'))
    evil_blk = evil[BLK_SZ:2 * BLK_SZ]

    # copy and paste
    victim = victim[:-BLK_SZ]
    victim += evil_blk

    return victim
Exemple #14
0
def aes_cbc_encrypt(key, iv, stream):
    fail_msg = "stream should be a multiple of %d, size actually: %d" \
           % (BLOCK_SIZE_IN_BYTES, len(stream))
    assert len(stream) % BLOCK_SIZE_IN_BYTES == 0, fail_msg

    blocks = block_split(stream)

    result = []
    for idx, pt_block in enumerate(blocks):
        last_block = iv if idx == 0 else result[-1]

        # pad block if its too small...
        # TODO: should only be needed on the last block
        if len(pt_block) < BLOCK_SIZE_IN_BYTES:
            pt_block = pkcs7_pad(pt_block, BLOCK_SIZE_IN_BYTES)

        ct_block = aes_ecb_encrypt(key, repeating_xor(last_block, pt_block))
        result.append(ct_block)

    return bytes().join(result)
Exemple #15
0
def encryption_oracle(plaintext):
    rand_key = get_rand_bytes(16)

    rand_size1 = random.randint(5, 10)
    rand_buf1 = get_rand_bytes(rand_size1)

    rand_size2 = random.randint(5, 10)
    rand_buf2 = get_rand_bytes(rand_size2)

    plainbuf = rand_buf1 + plaintext + rand_buf2
    plainbuf_padded = challenge9.pkcs7_pad(16, plainbuf)

    if random.randrange(2):
        mode = "ecb"
        encbuf = challenge7.encrypt_aes_128_ecb(rand_key, plainbuf_padded)
    else:
        mode = "cbc"
        rand_iv = get_rand_bytes(16)
        encbuf = challenge10.encrypt_aes_128_cbc(rand_key, rand_iv, plainbuf_padded)

    return encbuf, mode
Exemple #16
0
    def _handle_client(self, conn):
        """
        Give client encrypted data, which is in the form: length_of_message
        (little endian) || encrypted data.

        :param conn: socket object to talk to client
        """
        print("[*] Got client: waiting for text to encrypt")
        text = self._get_response(conn)
        print("[*] Got plaintext, encrypting...")

        # AES(user_text || unknown text)
        text += self._unknown
        new_text = pkcs7_pad(text, 16)
        ctext = self._cipher.encrypt(new_text)

        clen = struct.pack("I", int(len(ctext)))
        conn.send(clen)
        conn.send(ctext)
        print("[*] Sent encrypted data, closing")
        conn.close()
Exemple #17
0
def aes_cbc_encrypt(plaintext, key, iv):
    blocksize = 16
    prev_block = iv

    ciphertext = b''
    blocks = [
        plaintext[i:i + blocksize] for i in range(0, len(plaintext), blocksize)
    ]

    # Mode is ECB, no cheating :)
    cipher = AES.new(key, AES.MODE_ECB)

    for block in blocks:
        if (len(block) < blocksize):
            block = pkcs7_pad(block, blocksize)
        combined_block = xor(block, prev_block)
        cipher_block = cipher.encrypt(combined_block)
        prev_block = cipher_block
        ciphertext += cipher_block

    return ciphertext
def aes_cbc_encrypt(pt, key, iv):
    # pad if needed
    pt_padded = pkcs7_pad(pt, BLK_SZ)
    pt_chunks = chunk(pt_padded, BLK_SZ)

    prev_blk = iv
    ct_blks = []
    for pt_blk in pt_chunks:
        # xor with prev blk
        pt_xored = xor(prev_blk, pt_blk)

        # ECB encrypt
        ct_blk = encrypt_aes_ecb(pt_xored, key)
        ct_blks.append(ct_blk)

        # store as prev blk
        prev_blk = ct_blk

    ct_s = functools.reduce(lambda a, b: a + b, ct_blks)

    return ct_s
def encryption_oracle(x):
    if type(x) == str:
        x = bytearray(x, "utf-8")
    bytes_append_len = 5 + secrets.randbelow(6)
    bytes_prepend_len = 5 + secrets.randbelow(6)

    bytes_appended = bytearray(secrets.token_bytes(bytes_append_len))
    bytes_prepended = bytearray(secrets.token_bytes(bytes_prepend_len))

    pt = pkcs7_pad(bytes_prepended + x + bytes_appended, 16)

    encryption_scheme = secrets.randbelow(2)

    if (encryption_scheme == ECB_MODE):
        # do ECB
        ct = encrypt_aes_ecb(pt, gen_aes_key())
    elif (encryption_scheme == CBC_MODE):
        # do CBC
        ct = aes_cbc_encrypt(pt, gen_aes_key(), secrets.token_bytes(BLK_SZ))

    return ct, encryption_scheme
Exemple #20
0
def func1(key):
    strings = [
        "MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=",
        "MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=",
        "MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==",
        "MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==",
        "MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl",
        "MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==",
        "MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==",
        "MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=",
        "MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=",
        "MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93"
    ]

    choice = base64.b64decode(random.choice(strings))
    choice_padded = challenge9.pkcs7_pad(16, choice)

    iv = challenge11.get_rand_bytes(16)

    ciphertext = challenge10.encrypt_aes_128_cbc(key, iv, choice_padded)

    return choice, ciphertext, iv
def encryption_oracle(text):
    # random key
    key = os.urandom(16)
    # random encryption
    flip = random.randint(0, 1)
    if flip:
        IV = os.urandom(16)
        cipher = AES_CBC(key, IV)
        cbc = True
    else:
        cipher = AES.new(key, AES.MODE_ECB)
        cbc = False

    prefix = random.randint(5, 10)
    postfix = random.randint(5, 10)
    random_text = os.urandom(prefix + postfix)
    new_text = random_text[:prefix] + text + random_text[postfix:]

    end = len(new_text) % 16
    pad = pkcs7_pad(new_text[-end:], 16)
    new_text = new_text[:-end] + pad

    return (cipher.encrypt(new_text), cbc)
Exemple #22
0
def create_admin(pt, ct):
    """
    Consider the CBC decryption algorithm:
        P_i = D_k(C_i) XOR C_i-1; C_0 = IV for all blocks i
    We wish to construct a modified CT C' that when decrypted gives us the
    desired string ';admin=true;'. So, if we were to find C' such that the ith
    block would contain P_i' = ';admin=true;\x04\x04\x04\x04', we need to find
    C'_i-1 = P_i' XOR D_k(C_i). Since P_i = D_k(C_i) XOR C_i-1 and we have
    both P and C (and hence P_i and C_i-1), we can rewrite
    D_k(C_i) = P_i XOR C_i-1. So, C'_i-1 = P_i' XOR P_i XOR C_i-1.
    Assume we know the blocksize is 16 bytes.
    """

    blocksize = 16
    idx = 2  # Rewrite the second block of the CT to produce a PT with a
    # scrambled second block and our target 3rd block. idx is i-1
    block_text = pkcs7_pad(';admin=true;', blocksize)
    ct_blocks = [ct[i:i + blocksize] for i in range(0, len(ct), blocksize)]
    pt_blocks = [pt[i:i + blocksize] for i in range(0, len(pt), blocksize)]
    ct_new_block = xorstr(xorstr(block_text, pt_blocks[idx + 1]),
                          ct_blocks[idx])
    ct_blocks[idx] = ct_new_block
    return ''.join(ct_blocks)
Exemple #23
0
def decrypt_profile(key, enc_profile):
    plain_profile = challenge7.decrypt_aes_128_ecb(key, enc_profile)
    unpadded_profile = challenge9.pkcs7_unpad(16, plain_profile)

    return unpadded_profile


if __name__ == "__main__":
    random_key = challenge11.get_rand_bytes(16)

    enc_blocks = []

    input1 = "A" * 13
    enc_profile1 = encrypt_profile(random_key, profile_for(input1))
    # first 2 encrypted blocks decrypt to:
    # email=AAAAAAAAAAAAA&uid=10&role=
    enc_blocks.append(enc_profile1[:32])

    input2 = "A" * (16 - len("email=")) + challenge9.pkcs7_pad(16, "admin")
    enc_profile2 = encrypt_profile(random_key, profile_for(input2))
    # second encrypted block decrypts to:
    # admin\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b
    enc_blocks.append(enc_profile2[16:32])

    new_enc_profile = "".join(enc_blocks)
    plain_profile = decrypt_profile(random_key, new_enc_profile)
    print plain_profile

    profile_obj = kv_parse(plain_profile)
    print profile_obj
def profile_for(x):
    x = x.replace("&", "")
    x = x.replace("=", "")
    d = {'email': x, 'uid': 10, 'role': 'user'}

    return encrypt_aes_ecb(pkcs7_pad(obj_to_qs(d), BLK_SZ), KEY)
Exemple #25
0
def encrypt_profile(key, profile):
    padded_profile = challenge9.pkcs7_pad(16, profile)
    enc_profile = challenge7.encrypt_aes_128_ecb(key, padded_profile)

    return enc_profile