def discover_secret_length(block_size, padding_length):
    if padding_length % block_size == 0:
        pad_for_padding = ""
    else:
        pad_for_padding = "X" * (block_size - padding_length % block_size)
        assert len(pad_for_padding) < block_size

    tried = "A" * block_size * 2
    plaintext = string_to_bytearray(pad_for_padding + tried)
    ciphertext = encryption_oracle_ecb(plaintext)
    initial_length = len(ciphertext)

    # first two controlled blocks are identical
    padding_ciphertext_length = padding_length + len(pad_for_padding)
    controlled_ciphertext = ciphertext[padding_ciphertext_length:]
    assert controlled_ciphertext[0:block_size] == controlled_ciphertext[
        block_size:block_size * 2]

    # detect when there is a change in ciphertext length
    length_detected = False
    while not length_detected:
        tried += "B"
        plaintext = string_to_bytearray(tried)
        ciphertext_length = len(encryption_oracle_ecb(plaintext))

        if ciphertext_length > initial_length:
            length_detected = True
            payload_length_at_change = len(tried)
            new_length = ciphertext_length

    # padding used is block_size
    return new_length - payload_length_at_change - block_size - padding_length
def discover_block_size_in_bytes():
    tried = ""
    plaintext = string_to_bytearray(tried)
    initial_length = len(encryption_oracle_ecb(plaintext))

    # detect when there is a change in ciphertext length
    length_detected = False
    while not length_detected:
        tried += "A"
        plaintext = string_to_bytearray(tried)
        ciphertext_length = len(encryption_oracle_ecb(plaintext))

        if ciphertext_length > initial_length:
            length_detected = True
            payload_length_at_change = len(tried)
            new_length = ciphertext_length

    # find the block size
    block_size_detected = False
    while not block_size_detected:
        tried += "A"
        plaintext = string_to_bytearray(tried)
        ciphertext_length = len(encryption_oracle_ecb(plaintext))

        if ciphertext_length > new_length:
            block_size_detected = True

    return len(tried) - payload_length_at_change
Ejemplo n.º 3
0
def test_aes_ecb():
    # sanity check for encryption/decryption
    test_key = string_to_bytearray("A"*16)
    test_text = string_to_bytearray("12345678"*2)

    enc = encrypt_aes_128_ecb(test_text, test_key)
    if decrypt_aes_128_ecb(enc, test_key) != test_text:
        raise Exception("aes ecb is not working properly !!!")
Ejemplo n.º 4
0
def main():
    block = string_to_bytearray("YELLOW SUBMARINE")
    expected_pad_20 = string_to_bytearray("YELLOW SUBMARINE\x04\x04\x04\x04")

    padded = pkcs7_pad(block, 20)
    if padded == expected_pad_20:
        print("challenge 2.9 completed.")
    else:
        print("challenge 2.9 failed.")
Ejemplo n.º 5
0
def test_aes_cbc():
    # sanity check for encryption/decryption
    test_key = string_to_bytearray("A" * 16)
    test_text = string_to_bytearray("12345678" * 4)
    test_iv = string_to_bytearray("B" * 16)
    encrypted = encrypt_aes_cbc(test_text, test_key, test_iv)
    decrypted = decrypt_aes_cbc(encrypted, test_key, test_iv)
    if decrypted != test_text:
        raise Exception("aes cbc is not working properly !!!")
Ejemplo n.º 6
0
def ctr_bitflip():
    user_input = "AadminZtrueZ"
    desired = ";admin=true;"

    ciphertext = encrypt_params(user_input)
    ciphertext_user_input = ciphertext[32:32 + len(user_input)]

    delta = xor(string_to_bytearray(user_input), string_to_bytearray(desired))
    new_ciphertext_flipped = xor(ciphertext_user_input, delta)

    new_ciphertext = ciphertext[:32] + new_ciphertext_flipped + ciphertext[
        32 + len(user_input):]

    return new_ciphertext
Ejemplo n.º 7
0
def encrypt_user_data_cbc(user_data):
    user_data = user_data.replace(";", "")
    user_data = user_data.replace("=", "")
    plaintext = "comment1=cooking%20MCs;userdata=" + user_data + ";comment2=%20like%20a%20pound%20of%20bacon"

    to_encrypt = pad_to_mod_16(string_to_bytearray(plaintext))
    return encrypt_aes_cbc(to_encrypt, oracle_key, iv)
def break_mt19937_stream_cipher(ciphertext):
    for key_candidate in range(0, 2**16 - 1):
        message = cipher_decrypt(ciphertext, key_candidate)
        if message[len(message) - 14:] == string_to_bytearray("A" * 14):
            return key_candidate

    raise Exception('key not found')
Ejemplo n.º 9
0
def encrypt_params(user_input):
    user_input_stripped = user_input.replace(";", "").replace("=", "")

    prefix = "comment1=cooking%20MCs;userdata="
    suffix = ";comment2=%20like%20a%20pound%20of%20bacon"

    message = string_to_bytearray(prefix + user_input_stripped + suffix)
    return encrypt_aes_ctr(message, KEY, NONCE)
def main():
    message = string_to_bytearray(
        "comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20pound%20of%20bacon"
    )
    append = string_to_bytearray(";admin=true")

    signature = sign(message)
    assert verify_signature(signature, message)

    forge_signature_candidates = forge_signature(message, signature, append)

    forged = [(f, m) for (f, m) in forge_signature_candidates
              if verify_signature_admin(f, m)]
    if len(forged) > 0:
        print("challenge 4.29 completed.")
    else:
        print("challenge 4.29 failed.")
def discover_padding_length(block_size):
    magic_blocks_number = 5
    tried = "A" * block_size * magic_blocks_number
    plaintext = string_to_bytearray(tried)
    ciphertext = encryption_oracle_ecb(plaintext)

    r = _check_magic_blocks_number(magic_blocks_number, ciphertext, block_size)
    i = 0
    while r is None:
        i += 1
        plaintext = string_to_bytearray(i * "B" + tried)
        ciphertext = encryption_oracle_ecb(plaintext)
        r = _check_magic_blocks_number(magic_blocks_number, ciphertext,
                                       block_size)

    # we "padded" the padding
    padding_length = r * block_size - i
    return padding_length
Ejemplo n.º 12
0
def main():
    test_aes_ecb()

    with open("7.txt", "r") as f: ciphertext_b64 = f.read().replace("\n", "")
    ciphertext_bt = base64_to_bytearray(ciphertext_b64)
    key = string_to_bytearray("YELLOW SUBMARINE")

    message = decrypt_aes_128_ecb(ciphertext_bt, key)
    assert b"I'm back and I'm ringin' the bell" in message
    print("challenge 1.7 completed.")
Ejemplo n.º 13
0
def main():
    key = crypto_random_bytes(16)
    message = string_to_bytearray("Commitment")

    h1 = sha1_keyed_mac(key, message)
    h2 = sha1_keyed_mac(key, message + b"X")

    if h1 and h2 and h1 != h2:
        print("challenge 4.28 completed.")
    else:
        print("challenge 4.28 failed.")
Ejemplo n.º 14
0
def main():
    test_aes_ctr()

    ciphertext_b64 = 'L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ=='
    ciphertext_bt = base64_to_bytearray(ciphertext_b64)

    key = string_to_bytearray("YELLOW SUBMARINE")
    nonce = bytearray([0] * 8)
    message = decrypt_aes_ctr(ciphertext_bt, key, nonce)

    #print message
    assert b"VIP Let's kick it" in message
    print("challenge 3.18 completed.")
Ejemplo n.º 15
0
def main():
    test_aes_cbc()

    with open("10.txt", "r") as f:
        ciphertext_b64 = f.read().replace("\n", "")
    ciphertext_bt = base64_to_bytearray(ciphertext_b64)

    key = string_to_bytearray("YELLOW SUBMARINE")
    iv = bytearray([0] * 16)

    message = decrypt_aes_cbc(ciphertext_bt, key, iv)
    assert b"I'm back and I'm ringin' the bell" in message
    print("challenge 2.10 completed.")
Ejemplo n.º 16
0
def encrypt_user_data_cbc(user_data):
    user_data = user_data.replace(";", "")
    user_data = user_data.replace("=", "")

    prefix = "comment1=cooking%20MCs;userdata="
    suffix = ";comment2=%20like%20a%20pound%20of%20bacon"

    plaintext = string_to_bytearray(prefix + user_data + suffix)

    to_encrypt = pad_to_mod_16(plaintext)
    ciphertext = encrypt_aes_cbc(to_encrypt, oracle_key, iv)

    return ciphertext
def discover_secret_length(block_size):
    tried = "A" * block_size * 2
    plaintext = string_to_bytearray(tried)
    ciphertext = encryption_oracle_ecb(plaintext)
    initial_length = len(ciphertext)

    # first two blocks are identical
    assert ciphertext[0:block_size] == ciphertext[block_size:block_size * 2]

    # detect when there is a change in ciphertext length
    length_detected = False
    while not length_detected:
        tried += "B"
        plaintext = string_to_bytearray(tried)
        ciphertext_length = len(encryption_oracle_ecb(plaintext))

        if ciphertext_length > initial_length:
            length_detected = True
            payload_length_at_change = len(tried)
            new_length = ciphertext_length

    # padding used is block_size
    return new_length - payload_length_at_change - block_size
Ejemplo n.º 18
0
def hmac(key, message):
    if (len(key) > BLOCKSIZE):
        key = bytearray(sha1(key).decode(
            'hex'))  # keys longer than BLOCKSIZE are shortened

    if (len(key) < BLOCKSIZE):
        # keys shorter than BLOCKSIZE are zero-padded (where + is concatenation)
        key = key + bytearray([0x00] *
                              (BLOCKSIZE - len(key)))  # Where * is repetition.

    o_key_pad = xor(bytearray([0x5c] * BLOCKSIZE), key)
    i_key_pad = xor(bytearray([0x36] * BLOCKSIZE), key)

    h1 = sha1(i_key_pad + string_to_bytearray(message))
    return sha1(o_key_pad + hexstr2bytearray(h1))
def find_secret(block_size, secret_length):
    discovered_so_far = bytearray([])

    for i in range(secret_length):
        blocks_to_craft = len(discovered_so_far) // block_size + 1
        padding_str = "A" * (blocks_to_craft * block_size - 1 -
                             len(discovered_so_far))
        padding = string_to_bytearray(padding_str)

        assert (len(padding) + len(discovered_so_far) + 1) % block_size == 0

        found = find_one_byte(padding, discovered_so_far)
        discovered_so_far.append(found)

    return discovered_so_far
Ejemplo n.º 20
0
def main():
    s1 = string_to_bytearray("ICE ICE BABY\x04\x04\x04\x04")
    s2 = string_to_bytearray("ICE ICE BABY\x05\x05\x05\x05")
    s3 = string_to_bytearray("ICE ICE BABY\x01\x02\x03\x04")

    assert valid_pkcs7_padding(s1) == True
    assert valid_pkcs7_padding(s2) == False
    assert valid_pkcs7_padding(s3) == False

    unpad_pkcs7(s1)

    try:
        unpad_pkcs7(s2)
        raise Exception("challenge 2.15 failed.")
    except ValueError as e:
        pass

    try:
        unpad_pkcs7(s3)
        raise Exception("challenge 2.15 failed.")
    except ValueError as e:
        pass

    print("challenge 2.15 completed.")
Ejemplo n.º 21
0
def main():
    true_modes = []
    detected_modes = []

    for trial in range(0, 100):
        crafted_plaintext = string_to_bytearray("A" * 64)

        ciphertext, true_mode = encryption_oracle_ecb_cbc(crafted_plaintext)
        detected_mode = detection_oracle(ciphertext)

        true_modes.append(true_mode)
        detected_modes.append(detected_mode)

    if detected_modes == true_modes:
        print("challenge 2.11 completed.")
    else:
        print("challenge 2.11 failed.")
def break_little_harder_way():
    newtext = string_to_bytearray('FIXED VALUE')
    chunk_length = len(newtext)

    chunks = unequal_chunks(ciphertext, chunk_length)
    keystream = bytearray([])

    for ix, chunk in enumerate(chunks):
        start = ix * chunk_length
        end = start + len(chunk)

        new_ciphertext = edit(start, newtext)[start:end]

        keystream_chunk = xor(new_ciphertext, newtext[:len(new_ciphertext)])
        keystream.extend(keystream_chunk)

    return xor(ciphertext, keystream)
def find_secret(block_size, padding_length, secret_length):
    if padding_length % block_size == 0:
        pad_for_padding = ""
    else:
        pad_for_padding = "X" * (block_size - padding_length % block_size)
        assert len(pad_for_padding) < block_size

    discovered_so_far = bytearray([])

    for i in range(secret_length):
        blocks_to_craft = len(discovered_so_far) // block_size + 1
        controlled_str = pad_for_padding + "A" * (
            blocks_to_craft * block_size - 1 - len(discovered_so_far))
        controlled = string_to_bytearray(controlled_str)

        assert (padding_length + len(controlled) + len(discovered_so_far) +
                1) % block_size == 0

        uninteresting_junk_length = padding_length + len(pad_for_padding)
        found = find_one_byte(controlled, uninteresting_junk_length,
                              len(pad_for_padding), discovered_so_far)
        discovered_so_far.append(found)

    return discovered_so_far
Ejemplo n.º 24
0
from utils import string_to_bytearray, xor, bytearray_to_hex_string

text = "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal"
message = string_to_bytearray(text)
key_string = "ICE"
key = string_to_bytearray(key_string)
expected = "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272\
a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f"

def encrypt_repeating_key(m, k):
    key_multiplier = len(m) // len(k)
    key_candidate = k * key_multiplier
    key_candidate += k[:len(m)-len(key_candidate)]

    xored = xor(m, key_candidate)
    return xored

def main():
    xored = encrypt_repeating_key(message, key)
    if bytearray_to_hex_string(xored) == expected:
        print("challenge 1.5 completed.")
    else:
        print("challenge 1.5 failed.")

if __name__ == '__main__':
    main()
Ejemplo n.º 25
0
def encrypt_profile_for(email):
    profile = string_to_bytearray(profile_for(email))
    to_encrypt = pad_to_mod_16(profile)
    return encrypt_aes_128_ecb(to_encrypt, oracle_key)
def detect_ecb_mode(block_size):
    crafted_payload = string_to_bytearray("A" * block_size * 3)
    ciphertext = encryption_oracle_ecb(crafted_payload)
    return detection_oracle(ciphertext)
import sys
sys.path.insert(0, '../set_1_basics')
sys.path.insert(0, '../set_2_block_crypto')
sys.path.insert(0, '../set_3_block_stream_crypto')
from utils import unequal_chunks, xor, string_to_bytearray
from aes_ctr_mode import encrypt_aes_ctr, decrypt_aes_ctr

with open('25.txt', 'r') as f:
    message = string_to_bytearray(f.read().replace("\n", ""))
KEY = string_to_bytearray("YELLOW SUBMARINE")
NONCE = bytearray([0] * 8)
ciphertext = encrypt_aes_ctr(message, KEY, NONCE)


def edit(offset, newtext):
    m = decrypt_aes_ctr(ciphertext, KEY, NONCE)
    m[offset:offset + len(newtext)] = newtext

    return encrypt_aes_ctr(m, KEY, NONCE)


def break_easy_way():
    total_length = len(ciphertext)

    newtext = bytearray([0] * total_length)
    offset = 0

    keystream = edit(offset, newtext)
    return xor(ciphertext, keystream)

Ejemplo n.º 28
0
 def hkdf(self):
     ss = string_to_bytearray(str(self.shared_secret))
     return hex_string_to_bytearray(sha1(ss))[:16]
Ejemplo n.º 29
0
from utils import base64_to_bytearray, hamming_distance, string_to_bytearray, unequal_chunks
from single_byte_xor_cipher import break_xor_cipher
from utils import alpha_and_printable_heuristic
from itertools import zip_longest
from repeating_key_xor import encrypt_repeating_key
from operator import itemgetter

assert hamming_distance(string_to_bytearray("this is a test"),
                        string_to_bytearray("wokka wokka!!!")) == 37


# block contains a || b
def normalized_edit_distance(block, key_size):
    a = block[0:key_size]
    b = block[key_size:(key_size * 2)]
    edit_distance = hamming_distance(a, b)
    return 1.0 * edit_distance / key_size


def find_key_length(ciphertext):
    results = []

    for key_size in range(2, 40):
        block_length = 2 * key_size
        nblocks = len(ciphertext) // block_length
        blocks = unequal_chunks(ciphertext, block_length)

        distances = [normalized_edit_distance(i, key_size) for i in blocks]
        average = sum(distances) / nblocks

        results.append((average, key_size))
Ejemplo n.º 30
0
import sys
sys.path.insert(0, '../set_1_basics')
sys.path.insert(0, '../set_2_block_crypto')
sys.path.insert(0, '../set_3_block_stream_crypto')
from utils import unequal_chunks, xor, string_to_bytearray
from aes_ctr_mode import encrypt_aes_ctr, decrypt_aes_ctr

KEY = string_to_bytearray("YELLOW SUBMARINE")
NONCE = bytearray([0] * 8)


def encrypt_params(user_input):
    user_input_stripped = user_input.replace(";", "").replace("=", "")

    prefix = "comment1=cooking%20MCs;userdata="
    suffix = ";comment2=%20like%20a%20pound%20of%20bacon"

    message = string_to_bytearray(prefix + user_input_stripped + suffix)
    return encrypt_aes_ctr(message, KEY, NONCE)


def check_admin(ciphertext):
    message = decrypt_aes_ctr(ciphertext, KEY, NONCE)
    return b";admin=true;" in message


def ctr_bitflip():
    user_input = "AadminZtrueZ"
    desired = ";admin=true;"

    ciphertext = encrypt_params(user_input)