예제 #1
0
    def test_ch27(self):
        key = generate_random_key(16)
        enc_oracle = partial(encryption_oracle, key=key, blocksize=16)
        dec_oracle = partial(decryption_oracle, key=key, blocksize=16)

        recovered_key = break_cbc_oracle(enc_oracle, dec_oracle)
        self.assertEquals(recovered_key, key)
예제 #2
0
def break_ctr_api(plaintext, ctr_key=None):
    '''
    Imagine the "edit" function was exposed to attackers by means of an API call that didn't
    reveal the key or the original plaintext; the attacker has the ciphertext and controls the
    offset and "new text".

    Recover the original plaintext.

    ciphera = a_plaintext xor keystream
    cipherb = b_plaintext xor keystream
    ciphera xor cipherb = a_plaintext xor keystream xor b_plaintext xor keystream
    ciphera xor cipherb xor b_plaintext = a_plaintext
    '''
    if ctr_key is None:
        ctr_key = generate_random_key()
    ciphertext = aes_ctr(plaintext, ctr_key)

    def api(offset, newtext):
        return edit_ctr_cipher(ciphertext, ctr_key, offset, newtext)

    a_cipher = ciphertext
    b_plaintext = b'A' * len(ciphertext)
    b_cipher = api(0, b_plaintext)
    return bytes(
        [a ^ b ^ c for a, b, c in zip(a_cipher, b_cipher, b_plaintext)])
예제 #3
0
    def test_ch17(self):
        key = generate_random_key()
        oracle = encryption_get_oracle_func(key, cbc_padding_oracle)

        lst = [
            "MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=",
            "MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=",
            "MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==",
            "MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==",
            "MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl",
            "MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==",
            "MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==",
            "MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=",
            "MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=",
            "MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93"
        ]

        for plaintext in lst:
            #test funcs
            ciphertext = produce_ciphertext(plaintext, key)
            self.assertTrue(oracle(ciphertext))

            self.assertEqual(
                unpadpkcs7(break_cbc_padding_oracle(oracle, ciphertext)),
                plaintext)
예제 #4
0
    def test_ch16(self):
        key = generate_random_key()

        dec_oracle = encryption_get_oracle_func(key, decryption_oracle16)
        enc_oracle = encryption_get_oracle_func(key, encryption_oracle16)

        self.assertIn("admin=true", break_cbc_oracle(enc_oracle, dec_oracle))
예제 #5
0
    def test_ch13(self):
        key = generate_random_key()
        dec_oracle = encryption_get_oracle_func(key, decryption_oracle13)
        enc_oracle = encryption_get_oracle_func(key, encryption_oracle13)

        obj = cut_and_paste_attack("*****@*****.**", enc_oracle,
                                   dec_oracle)
        self.assertEqual("admin", obj["role"])
예제 #6
0
    def test_ch26(self):

        key = generate_random_key()

        dec_oracle = partial(aes_ctr_encrypt_decrypt,
                             key=key,
                             nonce=form_nonce(0))
        enc_oracle = partial(aes_ctr_encryption_oracle, key=key, blocksize=16)

        self.assertIn("admin=true",
                      aes_ctr_break_bitflipping(enc_oracle, dec_oracle))
예제 #7
0
    def test_ch20(self):
        plaintexts = []
        ciphertexts = []

        key = generate_random_key(16)

        with open('static/19.txt', 'r') as myfile:
            for line in myfile.read().splitlines():
                plaintexts.append(b64decode(line))

        for plaintext in plaintexts:
            nonce = form_nonce(0)
            ciphertexts.append(aes_ctr_encrypt_decrypt(plaintext, key, nonce))

        raise NotImplementedError
예제 #8
0
    def test_ch12(self):
        cleartext = b64decode(
            "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg\
aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq\
dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg\
YnkK")
        key = generate_random_key()
        oracle = encryption_get_oracle_func(key, encryption_oracle2)

        mode = check_block_mode_decoupled(oracle)
        self.assertEqual(mode, AES_ECB_MODE)

        block_size = guess_block_size(oracle)
        self.assertEqual(16, block_size)

        self.assertEqual(break_ecb_oracle(oracle, block_size), cleartext)
예제 #9
0
    def test_ch19(self):
        # this is a many time pad problem
        plaintexts = []
        ciphertexts = []

        key = generate_random_key(16)

        with open('static/19.txt', 'r') as myfile:
            for line in myfile.read().splitlines():
                plaintexts.append(b64decode(line))

        for plaintext in plaintexts:
            nonce = form_nonce(0)
            ciphertexts.append(aes_ctr_encrypt_decrypt(plaintext, key, nonce))

        break_ctr_reused_nonce_substitutions(ciphertexts)
        raise NotImplementedError
예제 #10
0
    def test_ch25(self):
        key = generate_random_key(16)
        with open('static/25.txt', 'r') as myfile:
            cipher = b64decode(myfile.read())
        plaintext = unpadpkcs7(aes_ecb_decrypt(cipher, "YELLOW SUBMARINE"))
        nonce = form_nonce(0)

        ciphertext = aes_ctr_encrypt_decrypt(plaintext, key, nonce)

        edit_func = partial(edit_ciphertext, key=key)
        # test edit_ciphertext function
        result = edit_ciphertext(ciphertext, key, 32, "YELLOW")
        self.assertEquals(
            result,
            aes_ctr_encrypt_decrypt(plaintext[:32] + "YELLOW" + plaintext[38:],
                                    key, nonce))

        # break it
        self.assertEquals(break_edit_ciphertext(ciphertext, edit_func),
                          plaintext)
예제 #11
0
    def test_ch14(self):
        cleartext = b64decode(
            "Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg\
aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq\
dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg\
YnkK")
        key = generate_random_key()
        block_size = len(key)
        randomdata = Random.new().read(random.choice(range(1, 31)))
        oracle = partial(encryption_get_oracle_func(key, encryption_oracle14),
                         randomdata=randomdata)
        self.assertEqual(len(randomdata), get_random_data_length(oracle))

        filling_text = (block_size - (len(randomdata) % block_size)) * "A"

        out = break_ecb_oracle(oracle,
                               block_size,
                               filling_text,
                               startindex=len(filling_text) + len(randomdata))

        self.assertEqual(out, cleartext)
예제 #12
0
'''set3 solutions for cryptopals'''
import secrets
import random
import time
from Crypto.Cipher import AES
from set1 import bin_to_hex, hex_to_bin, hex_to_base64, base64_to_bin, encrypt_repeating_xor, aes_ecb_decrypt, fixed_xor, english_score
from set2 import pkcs7, validate_pkcs7, blockify, aes_cbc_encrypt, aes_cbc_decrypt, aes_ecb_encrypt, generate_random_key, unpad

GLOBAL_RANDOM_KEY = generate_random_key()
challenge_17_strings = [
    b"MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=",
    b"MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=",
    b"MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==",
    b"MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==",
    b"MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl",
    b"MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==",
    b"MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==",
    b"MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=",
    b"MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=",
    b"MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93"
]
def serve_cookie(iv=None):
    '''
    This function approximates AES-CBC encryption on a webserver. It serves up
    a "new" cookie to the user so when they make a request on the server the server
    can figure out who is talking to it.
    '''
    string_to_encode = challenge_17_strings[random.randint(0, len(challenge_17_strings) - 1)]
    return aes_cbc_encrypt(string_to_encode, GLOBAL_RANDOM_KEY, iv=iv), iv

def consume_cookie(cipher, iv=None):
예제 #13
0
    '''
    if ctr_key is None:
        ctr_key = generate_random_key()
    ciphertext = aes_ctr(plaintext, ctr_key)

    def api(offset, newtext):
        return edit_ctr_cipher(ciphertext, ctr_key, offset, newtext)

    a_cipher = ciphertext
    b_plaintext = b'A' * len(ciphertext)
    b_cipher = api(0, b_plaintext)
    return bytes(
        [a ^ b ^ c for a, b, c in zip(a_cipher, b_cipher, b_plaintext)])


challenge_26_aes_key = generate_random_key()


def challenge_26_encrypt(string_in):
    to_return = 'comment1=cooking%20MCs;userdata=' + string_in.replace(
        '=', '%3d').replace(
            ';', '%3b') + ';comment2=%20like%20a%20pound%20of%20bacon'
    to_return = str.encode(to_return)

    return aes_ctr(to_return, challenge_26_aes_key)


def challenge_26_detect_admin(cipher):
    decrypted = aes_ctr(cipher, challenge_26_aes_key)
    return decrypted.count(b";admin=true") > 0
예제 #14
0
 def test_ch11(self):
     key = generate_random_key()
     oracle = encryption_get_oracle_func(key, encryption_oracle1)
     for _ in range(20):
         result, correct_result = check_block_mode(oracle)
         self.assertEqual(result, correct_result)