Exemple #1
0
 def detect_single_byte_xor(ciphers):
     """Detects single byte xor cipher from the list of ciphers."""
     for cipher in ciphers:
         text, _ = FrequencyAnalyzer.break_single_byte_xor(cipher)
         if text and FrequencyAnalyzer.is_english(text):
             return text
     return None
Exemple #2
0
 def break_repeating_xor(cipher, key_len=0):
     """Breaks repeating key xor cipher. Returns (plaintext, key)"""
     key_len = key_len if key_len > 0 else Crypto.break_key_length(cipher)
     # Solve each block as if it was single-character XOR.
     key = ''.join([FrequencyAnalyzer.break_single_byte_xor(
         cipher[i::key_len])[1] for i in range(0, key_len)])
     return FrequencyAnalyzer.get_repeating_xor(cipher, key), key
Exemple #3
0
 def detect_single_byte_xor(ciphers):
     """Detects single byte xor cipher from the list of ciphers."""
     for cipher in ciphers:
         text, _ = FrequencyAnalyzer.break_single_byte_xor(cipher)
         if text and FrequencyAnalyzer.is_english(text):
             return text
     return None
Exemple #4
0
 def break_repeating_xor(cipher, key_len=0):
     """Breaks repeating key xor cipher. Returns (plaintext, key)"""
     key_len = key_len if key_len > 0 else Crypto.break_key_length(cipher)
     # Solve each block as if it was single-character XOR.
     key = ''.join([
         FrequencyAnalyzer.break_single_byte_xor(cipher[i::key_len])[1]
         for i in range(0, key_len)
     ])
     return FrequencyAnalyzer.get_repeating_xor(cipher, key), key
Exemple #5
0
 def flip_cipher_to_add_admin_cbc(aes_cbc, has_admin):
     """Flip bits in text until we get admin in cipher."""
     # this ensures at least one block has all X's
     block_size = 16
     cipher = aes_cbc('x' * 2 * block_size)
     flipper = FrequencyAnalyzer.get_repeating_xor('x' * block_size,
                                                   ';admin=true;')
     # XXXXX xor ;admin=true; xor XXXXX => ;admin=true;
     for i, block in enumerate(Crypto.get_blocks(cipher, block_size)):
         flipped_block = FrequencyAnalyzer.get_repeating_xor(flipper, block)
         flipped_cipher = (cipher[:i * block_size] + flipped_block +
                           cipher[(i + 1) * block_size:])
         if has_admin(flipped_cipher):
             return True
     return False
Exemple #6
0
def hmac_sha1(key, message):
    """HMAC implementation using sha1 as hash function"""
    blocksize = 64
    # keys longer than blocksize are shortened
    if (len(key) > blocksize):
        key = sha1(key)

    # keys shorter than blocksize are zero-padded
    if (len(key) < blocksize):
        key = key + b'\x00' * (blocksize - len(key))

    o_key_pad = FrequencyAnalyzer.get_repeating_xor('\x5c' * blocksize, key)
    i_key_pad = FrequencyAnalyzer.get_repeating_xor('\x36' * blocksize, key)

    return sha1(o_key_pad + sha1(i_key_pad + message))
Exemple #7
0
def hmac_sha1(key, message):
    """HMAC implementation using sha1 as hash function"""
    blocksize = 64
    # keys longer than blocksize are shortened
    if (len(key) > blocksize):
        key = sha1(key)

    # keys shorter than blocksize are zero-padded
    if (len(key) < blocksize):
        key = key + b'\x00' * (blocksize - len(key))

    o_key_pad = FrequencyAnalyzer.get_repeating_xor('\x5c' * blocksize, key)
    i_key_pad = FrequencyAnalyzer.get_repeating_xor('\x36' * blocksize, key)

    return sha1(o_key_pad + sha1(i_key_pad + message))
Exemple #8
0
 def test_break_single_byte_xor(self):
     """Challenge 3"""
     expected = "Cooking MC's like a pound of bacon"
     hex_str = Crypto.get_lines('data/3.txt')[0]
     cipher = binascii.unhexlify(hex_str)
     text, _ = FrequencyAnalyzer.break_single_byte_xor(cipher)
     self.assertEqual(expected, text)
Exemple #9
0
 def test_fixed_xor(self):
     """Challenge 2"""
     expected = binascii.unhexlify('746865206b696420646f6e277420706c6179')
     actual = FrequencyAnalyzer.get_repeating_xor(
         binascii.unhexlify('1c0111001f010100061a024b53535009181c'),
         binascii.unhexlify('686974207468652062756c6c277320657965'))
     self.assertEqual(expected, actual)
Exemple #10
0
 def flip_cipher_to_add_admin_cbc(aes_cbc, has_admin):
     """Flip bits in text until we get admin in cipher."""
     # this ensures at least one block has all X's
     block_size = 16
     cipher = aes_cbc('x'*2*block_size)
     flipper = FrequencyAnalyzer.get_repeating_xor(
         'x'*block_size, ';admin=true;')
     # XXXXX xor ;admin=true; xor XXXXX => ;admin=true;
     for i, block in enumerate(Crypto.get_blocks(cipher, block_size)):
         flipped_block = FrequencyAnalyzer.get_repeating_xor(flipper, block)
         flipped_cipher = (cipher[:i*block_size] +
                           flipped_block +
                           cipher[(i+1)*block_size:])
         if has_admin(flipped_cipher):
             return True
     return False
Exemple #11
0
 def test_break_single_byte_xor(self):
     """Challenge 3"""
     expected = "Cooking MC's like a pound of bacon"
     hex_str = Crypto.get_lines('data/3.txt')[0]
     cipher = binascii.unhexlify(hex_str)
     text, _ = FrequencyAnalyzer.break_single_byte_xor(cipher)
     self.assertEqual(expected, text)
Exemple #12
0
 def test_fixed_xor(self):
     """Challenge 2"""
     expected = binascii.unhexlify('746865206b696420646f6e277420706c6179')
     actual = FrequencyAnalyzer.get_repeating_xor(
         binascii.unhexlify('1c0111001f010100061a024b53535009181c'),
         binascii.unhexlify('686974207468652062756c6c277320657965'))
     self.assertEqual(expected, actual)
Exemple #13
0
 def extract_key_if_key_is_same_as_key(cipher, oracle):
     """Extract key given encrypt and decrypt functions.  Exploit the fact
     that key is same is IV."""
     bs = 16
     blocks = Crypto.get_blocks(cipher)
     cipher = blocks[2] + chr(0)*bs + blocks[2] + blocks[3]
     text = oracle(cipher)
     return FrequencyAnalyzer.get_repeating_xor(text[0:bs], text[2*bs:])
Exemple #14
0
 def extract_key_if_key_is_same_as_key(cipher, oracle):
     """Extract key given encrypt and decrypt functions.  Exploit the fact
     that key is same is IV."""
     bs = 16
     blocks = Crypto.get_blocks(cipher)
     cipher = blocks[2] + chr(0) * bs + blocks[2] + blocks[3]
     text = oracle(cipher)
     return FrequencyAnalyzer.get_repeating_xor(text[0:bs], text[2 * bs:])
Exemple #15
0
    def break_aes_using_padding_leak(cipher, init_vector, has_valid_padding):
        """Decrypts cipher given has_valid_padding function which decrypts
        and return true if result has valid padding, false otherwise. We will
        use this leak to break the cipher and return plaintext"""
        block_size = 16
        mutate = lambda text, i, c: text[:i] + c + text[i + 1:]
        # get padding size
        pad_size = 0
        # second_last block index
        sl_block = len(cipher) - block_size * 2
        for i in range(block_size):
            # check if pad_size is block_size - i
            change = 'b' if cipher[sl_block + i] == 'a' else 'a'
            if not has_valid_padding(mutate(cipher, sl_block + i, change),
                                     init_vector):
                pad_size = block_size - i
                break

        # we know pad size which means we know last pad_size bytes of result.
        prexor = FrequencyAnalyzer.get_repeating_xor(
            chr(pad_size) * pad_size,
            cipher[-pad_size - block_size:-block_size])
        iv_and_cipher = init_vector + cipher
        for i in range(len(prexor), len(cipher)):
            pad_size = (len(prexor) % block_size) + 1
            # decrypt byte at target_index in this iteration.
            target_index = len(cipher) - len(prexor) - 1
            for char in range(256):
                # temper iv_and_cipher
                attack = mutate(iv_and_cipher, target_index, chr(char))
                xor = FrequencyAnalyzer.get_repeating_xor(
                    chr(pad_size) * (pad_size - 1), prexor[:pad_size - 1])
                attack = attack[:target_index + 1] + xor
                # add next block
                attack = (attack +
                          iv_and_cipher[len(attack):len(attack) + block_size])
                flipped_iv = attack[:block_size]
                flipped_cipher = attack[block_size:]
                if has_valid_padding(flipped_cipher, flipped_iv):
                    prexor = chr(pad_size ^ char) + prexor
                    break
        blocks = zip(Crypto.get_blocks(iv_and_cipher),
                     Crypto.get_blocks(prexor))
        return Crypto.unpad_pkcs7(''.join(
            [FrequencyAnalyzer.get_repeating_xor(a, b) for a, b in blocks]))
Exemple #16
0
    def break_aes_using_padding_leak(cipher, init_vector, has_valid_padding):
        """Decrypts cipher given has_valid_padding function which decrypts
        and return true if result has valid padding, false otherwise. We will
        use this leak to break the cipher and return plaintext"""
        block_size = 16
        mutate = lambda text, i, c: text[:i] + c +  text[i+1:]
        # get padding size
        pad_size = 0
        # second_last block index
        sl_block = len(cipher) - block_size*2
        for i in range(block_size):
            # check if pad_size is block_size - i
            change = 'b' if cipher[sl_block+i] == 'a' else 'a'
            if not has_valid_padding(
                    mutate(cipher, sl_block+i, change), init_vector):
                pad_size = block_size - i
                break

        # we know pad size which means we know last pad_size bytes of result.
        prexor = FrequencyAnalyzer.get_repeating_xor(
            chr(pad_size)*pad_size, cipher[-pad_size-block_size:-block_size])
        iv_and_cipher = init_vector + cipher
        for i in range(len(prexor), len(cipher)):
            pad_size = (len(prexor) % block_size) + 1
            # decrypt byte at target_index in this iteration.
            target_index = len(cipher) - len(prexor) - 1
            for char in range(256):
                # temper iv_and_cipher
                attack = mutate(iv_and_cipher, target_index, chr(char))
                xor = FrequencyAnalyzer.get_repeating_xor(
                    chr(pad_size)*(pad_size-1), prexor[:pad_size-1])
                attack = attack[:target_index+1] + xor
                # add next block
                attack = (attack +
                          iv_and_cipher[len(attack):len(attack)+block_size])
                flipped_iv = attack[:block_size]
                flipped_cipher = attack[block_size:]
                if has_valid_padding(flipped_cipher, flipped_iv):
                    prexor = chr(pad_size^char) + prexor
                    break
        blocks = zip(
            Crypto.get_blocks(iv_and_cipher), Crypto.get_blocks(prexor))
        return Crypto.unpad_pkcs7(''.join(
            [FrequencyAnalyzer.get_repeating_xor(a, b) for a, b in blocks]))
Exemple #17
0
 def decrypt_cbc_using_ecb(cipher, key):
     """Implement AES CBC using AES ECB."""
     iv = '\x00'*16
     text = ''
     aes = AES.new(key, AES.MODE_ECB)
     for block in Crypto.get_blocks(cipher):
         temp = aes.decrypt(block)
         text += FrequencyAnalyzer.get_repeating_xor(temp, iv)
         iv = block
     return Crypto.unpad_pkcs7(text)
Exemple #18
0
 def encrypt_cbc_using_ecb(text, key):
     """Implement AES CBC using AES ECB."""
     iv = '\x00' * 16
     cipher = ''
     aes = AES.new(key, AES.MODE_ECB)
     for block in Crypto.get_blocks(Crypto.pad_pkcs7(text)):
         block = FrequencyAnalyzer.get_repeating_xor(block, iv)
         iv = aes.encrypt(block)
         cipher += iv
     return cipher
Exemple #19
0
 def encrypt_cbc_using_ecb(text, key):
     """Implement AES CBC using AES ECB."""
     iv = '\x00'*16
     cipher = ''
     aes = AES.new(key, AES.MODE_ECB)
     for block in Crypto.get_blocks(Crypto.pad_pkcs7(text)):
         block = FrequencyAnalyzer.get_repeating_xor(block, iv)
         iv = aes.encrypt(block)
         cipher += iv
     return cipher
Exemple #20
0
 def decrypt_cbc_using_ecb(cipher, key):
     """Implement AES CBC using AES ECB."""
     iv = '\x00' * 16
     text = ''
     aes = AES.new(key, AES.MODE_ECB)
     for block in Crypto.get_blocks(cipher):
         temp = aes.decrypt(block)
         text += FrequencyAnalyzer.get_repeating_xor(temp, iv)
         iv = block
     return Crypto.unpad_pkcs7(text)
Exemple #21
0
 def test_break_aes_ctr_fixed_nonce2(self):
     """Challenge 20"""
     block_size = 16
     quote = lambda t: t
     counter = lambda: chr(25) * block_size
     aes_ctr, _ = Crypto.generate_aes_oracle('', '', AES.MODE_CTR, quote,
                                             block_size, counter)
     texts = [base64.b64decode(l) for l in open('data/20.txt').readlines()]
     ciphers = [aes_ctr(text) for text in texts]
     expected = FrequencyAnalyzer.get_repeating_xor(ciphers[0],
                                                    texts[0])[:block_size]
     actual = Crypto.break_aes_ctr_with_fixed_nonce(ciphers, block_size)
     self.assertEquals(expected, actual)
Exemple #22
0
 def test_break_aes_ctr_fixed_nonce2(self):
     """Challenge 20"""
     block_size = 16
     quote = lambda t: t
     counter = lambda: chr(25)*block_size
     aes_ctr, _ = Crypto.generate_aes_oracle(
         '', '', AES.MODE_CTR, quote, block_size, counter)
     texts = [base64.b64decode(l) for l in open('data/20.txt').readlines()]
     ciphers = [aes_ctr(text) for text in texts]
     expected = FrequencyAnalyzer.get_repeating_xor(
         ciphers[0], texts[0])[:block_size]
     actual = Crypto.break_aes_ctr_with_fixed_nonce(ciphers, block_size)
     self.assertEquals(expected, actual)
Exemple #23
0
 def test_get_repeating_xor(self):
     """Challenge 5"""
     expected, one, two = Crypto.get_lines('data/5.txt')
     xor = FrequencyAnalyzer.get_repeating_xor(one + '\n' + two, "ICE")
     self.assertEqual(expected, binascii.hexlify(xor))
Exemple #24
0
 def test_get_repeating_xor(self):
     """Challenge 5"""
     expected, one, two = Crypto.get_lines('data/5.txt')
     xor = FrequencyAnalyzer.get_repeating_xor(one + '\n' + two, "ICE")
     self.assertEqual(expected, binascii.hexlify(xor))