Esempio n. 1
0
    def test_determine_randbytes_size_nominal_case(self):
        randbytes = rand_bytes_gen(47)
        encryption_oracle = gen_encryption_oracle(16, randbytes=randbytes)

        randbytes_size = determine_randbytes_size(encryption_oracle, 16)

        self.assertEqual(47, randbytes_size)
Esempio n. 2
0
def break_cbc_single_blk(
        cipher_blk1: bytes,
        cipher_blk2: bytes,
        padding_oracle: Callable[[bytes, bytes], bool]) \
        -> bytes:
    """
    params:
        cipher_blk1: encrypted block prior to `cipher_blk2` or IV if
                     `cipher_blk2` was the first encrypted block
        cipher_blk2: block to be decrypted
        padding_oracle: `valid_padding()`
    returns:
        decryption of `cipher_blk2`
    """
    intermediate_blk2 = b''
    plain_blk2 = b''

    for i in range(1, 17):
        target_byte = i.to_bytes(1, byteorder=sys.byteorder)
        atk_blk_prefix = rand_bytes_gen(16 - i)
        atk_blk_suffix = b''
        for k in range(len(intermediate_blk2)):
            atk_blk_suffix += xor(target_byte,
                                  get_byte_n(intermediate_blk2, k))
        for j in range(256):
            atk_byte = j.to_bytes(1, byteorder=sys.byteorder)
            if valid_padding(cipher_blk2,
                             atk_blk_prefix + atk_byte + atk_blk_suffix):
                break
        intermediate_blk2 = xor(atk_byte, target_byte) + intermediate_blk2
        plain_blk2 = xor(intermediate_blk2, get_byte_n(cipher_blk1,
                                                       -i)) + plain_blk2

    return plain_blk2
Esempio n. 3
0
def main():
    """
    decrypt contents of a file encrypted using AES-128 in ECB Mode
    encrypt decrypted plaintext using AES-128 in CTR Mode
    break CTR Mode encryption using `edit_oracle()`
    """
    key = b"YELLOW SUBMARINE"
    cipher = AES.new(key, AES.MODE_ECB)
    ecb = ECBMode(16, cipher.encrypt, cipher.decrypt)

    input_filename = os.path.join(pathlib.Path(__file__).parent, "input")
    with open(input_filename, "r") as input_file:
        base64_str = input_file.read()
    base64_bytes = base64_str.replace('\n', '').encode("utf-8")
    ecb_encrypted = base64.decodebytes(base64_bytes)

    plaintext = ecb.decrypt(ecb_encrypted)

    nonce = bytes(8)
    unknown_key = rand_bytes_gen(16)
    cipher = AES.new(unknown_key, AES.MODE_ECB)

    ctr = CTRMode(
        blksize=16,
        encrypt_blk=cipher.encrypt,
        decrypt_blk=cipher.decrypt,
        nonce=nonce
    )

    encrypted = ctr.encrypt(plaintext)

    edit_oracle = gen_edit_oracle(unknown_key, nonce)

    print(break_rand_access_ctr(encrypted, edit_oracle).decode())
Esempio n. 4
0
    def test_determine_randbytes_size_less_than_one_block_randbytes(self):
        randbytes = rand_bytes_gen(7)
        encryption_oracle = gen_encryption_oracle(16, randbytes=randbytes)

        randbytes_size = determine_randbytes_size(encryption_oracle, 16)

        self.assertEqual(7, randbytes_size)
Esempio n. 5
0
    def test_determine_randbytes_size_multiple_of_blksize(self):
        randbytes = rand_bytes_gen(32)
        encryption_oracle = gen_encryption_oracle(16, randbytes=randbytes)

        randbytes_size = determine_randbytes_size(encryption_oracle, 16)

        self.assertEqual(32, randbytes_size)
Esempio n. 6
0
    def test_recover_key_nominal_case(self):
        seed = int.from_bytes(rand_bytes_gen(1), "little")
        known_plaintext = b'A' * 14
        ciphertext = gen_ciphertext(known_plaintext, seed)

        recovered_seed = recover_key(known_plaintext, ciphertext, 8)

        self.assertEqual(seed, recovered_seed)
Esempio n. 7
0
def gen_ciphertext(plaintext: bytes, seed: int) -> bytes:
    """
    params:
        plaintext: bytes to encrypt
        seed: seed to use for encryption
    returns:
        MT19937Cipher encryption of `plaintext` prepended with a random number
        of random bytes using a random seed of 16 bytes
    """
    cipher = MT19937Cipher(seed)
    prefix = rand_bytes_gen(random.randint(1, 255))

    return cipher.encrypt(prefix+plaintext)
Esempio n. 8
0
def main():
    """
    append payload to message while maintaining a valid MAC
    """
    cookie = (b"comment1=cooking%20MCs;userdata=foo;comment2=%20like%20a%20"
              b"pound%20of%20bacon")
    key = rand_bytes_gen(random.randint(0, 128))
    authenticated_cookie = MAC.generate(cookie, key, SHA1)

    def validation_oracle(msg):
        return MAC.validate(msg, key, SHA1)

    payload = b";admin=true"
    attack_cookie = length_extension(
        authenticated_cookie,
        payload,
        validation_oracle
    )

    assert MAC.validate(attack_cookie, key, SHA1)
    print(attack_cookie)
Esempio n. 9
0
def encryption_oracle() -> Tuple[bytes, bytes]:
    """
    params:
        none
    returns:
        ciphertext: one of ten plaintexts encrypted using AES-128-CBC with `iv`
        iv: iv used to encrypt the ciphertext
    """
    plain_strs = (
        b"MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=",
        b"MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIH" +
        b"B1bXBpbic=",
        b"MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw" +
        b"==",
        b"MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==",
        b"MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl",
        b"MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==",
        b"MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==",
        b"MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=",
        b"MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=",
        b"MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93",
    )

    blksize = len(CONSISTENT_KEY)

    plain = base64.b64decode(plain_strs[random.randint(0,
                                                       len(plain_strs) - 1)])
    padded = PKCS7Padding.apply(plain, blksize)

    cipher = AES.new(CONSISTENT_KEY, AES.MODE_ECB)
    iv = rand_bytes_gen(blksize)
    cbc = CBCMode(blksize=blksize,
                  encrypt_blk=cipher.encrypt,
                  decrypt_blk=cipher.decrypt,
                  iv=iv)

    encrypted = cbc.encrypt(padded)

    return encrypted, iv
Esempio n. 10
0
import base64
from Crypto.Cipher import AES
import random
import sys
from typing import Callable, Tuple

from set1.challenge02.fixed_xor import xor
from set1.challenge07.ecb_mode import blocks
from set2.challenge09.pkcs7_padding import PKCS7Padding, \
    InvalidPaddingException
from set2.challenge10.cbc_mode import CBCMode
from set2.challenge11.rand_enc import rand_bytes_gen

CONSISTENT_KEY = rand_bytes_gen(16)


def encryption_oracle() -> Tuple[bytes, bytes]:
    """
    params:
        none
    returns:
        ciphertext: one of ten plaintexts encrypted using AES-128-CBC with `iv`
        iv: iv used to encrypt the ciphertext
    """
    plain_strs = (
        b"MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=",
        b"MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIH" +
        b"B1bXBpbic=",
        b"MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw" +
        b"==",
        b"MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==",
Esempio n. 11
0
 def test_rand_bytes_gen_zero_keysize_returns_empty_bytes(self):
     self.assertEqual(b'', rand_bytes_gen(0))
Esempio n. 12
0
    def test_rand_bytes_gen_nominal_case(self):
        key = rand_bytes_gen(16)

        self.assertEqual(16, len(key))
Esempio n. 13
0
 def test_rand_bytes_gen_negative_keysize_returns_empty_bytes(self):
     self.assertEqual(b'', rand_bytes_gen(-1))
Esempio n. 14
0
    def test_break_ecb_randbytes_zero_randbytes(self):
        unknownstr = b"YELLOW SUBMARINEEXTRA"
        randbytes = rand_bytes_gen(7)
        encryption_oracle = gen_encryption_oracle(16, unknownstr, randbytes)

        self.assertEqual(unknownstr, break_ecb(encryption_oracle))
Esempio n. 15
0
    def test_break_ecb_randbytes_size_multiple_of_blksize(self):
        unknownstr = b"YELLOW SUBMARINEEXTRA"
        randbytes = rand_bytes_gen(32)
        encryption_oracle = gen_encryption_oracle(16, unknownstr, randbytes)

        self.assertEqual(unknownstr, break_ecb(encryption_oracle))
Esempio n. 16
0
from Crypto.Cipher import AES
from typing import Callable

from set1.challenge02.fixed_xor import xor
from set1.challenge07.ecb_mode import get_block_n
from set2.challenge11.rand_enc import rand_bytes_gen
from set3.challenge18.ctr_mode import CTRMode

CONSISTENT_KEY = rand_bytes_gen(16)
CONSISTENT_NONCE = rand_bytes_gen(8)


# Copied from set2.challenge16.ctr_bitflip
# Very specific use-case so I chose to copy instead of refactoring with
# greater abstraction
# No need to retest (Famous last words :P)
# Changed to use CTRMode
def gen_encryption_oracle(blksize: int = 16, prefix: bytes = None, suffix: bytes = None) \
        -> Callable[[bytes], bytes]:
    """
    params:
        blksize: blocksize `encryption_oracle` should use
        prefix: bytes to prepend to message
        suffix: bytes to append to message
    returns:
        `encryption_oracle` method
    """
    if prefix is None:
        prefix = b"comment1=cooking%20MCs;userdata="

    if suffix is None: