Beispiel #1
0
 def value(self):
     # This was found "by hand", using the idea explored in the previous
     # challenge: concatenate our target snippet with the original one, 
     # and use the latter MAC code as the final MAC code of the whole 
     # message. Thus, the crafted code snippet will look like:
     #
     # alert('Ayo, the Wu is back!');        var x = ('<GARBAGE>as that?');
     #
     # where <GARBAGE> stands for the the concatenation of 16-byte PKCS7
     # padding and the XOR between the first block of the original snippet
     # and the MAC code of the first part of that message.
     # This script was tested on Chrome and worked OK (luckily, no "'"
     # appeared inside <GARBAGE>).
     
     # 2 spaces complete the second block, and 6 of them are just used
     # to complete block 3 and leave room for the 'var x' declaration.
     spaces = ' '*8
     var_x = 'var x = (\''
     prefix = '%s%s%s' % (self.TARGET_SNIPPET, spaces, var_x)
     padded_prefix = PKCS7Padder(prefix).value(self.BLOCK_SIZE)
     
     snippet = BlockString(self.SNIPPET, self.BLOCK_SIZE)
     prefix_hash = self.hash_function.hash(prefix)
     garbage = ByteXOR(snippet.get_block(0), prefix_hash).value()
     # last block is just "as that?');"
     last_block = snippet.get_block(-1)
     
     crafted_snippet = '%s%s%s' % (padded_prefix, garbage, last_block)
     return self.hash_function.hash(crafted_snippet)
Beispiel #2
0
    def value(self):
        # This was found "by hand", using the idea explored in the previous
        # challenge: concatenate our target snippet with the original one,
        # and use the latter MAC code as the final MAC code of the whole
        # message. Thus, the crafted code snippet will look like:
        #
        # alert('Ayo, the Wu is back!');        var x = ('<GARBAGE>as that?');
        #
        # where <GARBAGE> stands for the the concatenation of 16-byte PKCS7
        # padding and the XOR between the first block of the original snippet
        # and the MAC code of the first part of that message.
        # This script was tested on Chrome and worked OK (luckily, no "'"
        # appeared inside <GARBAGE>).

        # 2 spaces complete the second block, and 6 of them are just used
        # to complete block 3 and leave room for the 'var x' declaration.
        spaces = ' ' * 8
        var_x = 'var x = (\''
        prefix = '%s%s%s' % (self.TARGET_SNIPPET, spaces, var_x)
        padded_prefix = PKCS7Padder(prefix).value(self.BLOCK_SIZE)

        snippet = BlockString(self.SNIPPET, self.BLOCK_SIZE)
        prefix_hash = self.hash_function.hash(prefix)
        garbage = ByteXOR(snippet.get_block(0), prefix_hash).value()
        # last block is just "as that?');"
        last_block = snippet.get_block(-1)

        crafted_snippet = '%s%s%s' % (padded_prefix, garbage, last_block)
        return self.hash_function.hash(crafted_snippet)
Beispiel #3
0
 def value(self, message, k):
     block_string = BlockString(message, self.resumable_hash.block_size())
     # Compute the expandable message for this k.
     msg_generator = ExpandableMessageGenerator(self.hash_function, k)
     exp_message_state = msg_generator.state()
     # Build a mapping from intermediate states to block indices.
     state_map = self._build_state_map_for(block_string)
     # Find a linking block from the expandable message to the original
     # message.
     j, link = self._find_link(state_map, exp_message_state, k)
     # Now, generate a prefix having j blocks from the expandable message.
     prefix = msg_generator.value(j)
     # ...and remove first j+1 blocks from the original message.
     block_string.remove_blocks_until(j+1)
     return prefix + link + block_string.bytes()
Beispiel #4
0
 def value(self, message, k):
     block_string = BlockString(message, self.resumable_hash.block_size())
     # Compute the expandable message for this k.
     msg_generator = ExpandableMessageGenerator(self.hash_function, k)
     exp_message_state = msg_generator.state()
     # Build a mapping from intermediate states to block indices.
     state_map = self._build_state_map_for(block_string)
     # Find a linking block from the expandable message to the original
     # message.
     j, link = self._find_link(state_map, exp_message_state, k)
     # Now, generate a prefix having j blocks from the expandable message.
     prefix = msg_generator.value(j)
     # ...and remove first j+1 blocks from the original message.
     block_string.remove_blocks_until(j + 1)
     return prefix + link + block_string.bytes()
Beispiel #5
0
 def edit(self, ciphertext, offset, plaintext):
     if type(ciphertext) is BlockString:
         ciphertext = ciphertext.bytes()
     length = len(plaintext)
     key_bytes = self.keystream[offset:offset+length]
     new_bytes = ByteXOR(plaintext, key_bytes).value()
     new_ciphertext = ciphertext[:offset] + new_bytes +\
                      ciphertext[offset+length:]
     return BlockString(new_ciphertext)
Beispiel #6
0
 def _iterate_compress_function(self,
                                message,
                                initial_state=None,
                                block_callback=None):
     if not isinstance(message, BlockString):
         message = BlockString(message, self.block_size)
     if initial_state is None:
         initial_state = self.hash_function.initial_state()
     hash_function = self._init_hash_function(initial_state)
     for index, block in enumerate(message):
         new_state = hash_function._process_chunk(block)
         hash_function._update_registers_from(new_state)
         if block_callback is not None:
             block_callback(index, block, hash_function)
     return tuple(hash_function.state())
Beispiel #7
0
 def forge_from(self, message, mac):
     fake_message, fake_mac = self._build_fake_message_and_mac()
     fake_message = BlockString(fake_message, self.block_size)
     # Our new first block should be XORed with the original MAC. This, when
     # CBC-encrypted, will be like XORing the actual first block with a zero
     # IV.
     first_block = ByteXOR(fake_message.get_block(0), mac).value()
     # Remove first block; leave the rest untouched.
     fake_message.remove_block(0)
     # PKCS7-pad original message (since CBC encryption does so).
     padded_message = PKCS7Padder(message).value(self.block_size)
     crafted_message = padded_message + first_block + fake_message.bytes()
     return crafted_message, fake_mac
Beispiel #8
0
 def decrypt_with_cipher(self, ciphertext, cipher):
     if type(ciphertext) != BlockString:
         ciphertext = BlockString(ciphertext, self.block_size)
     return self._iterate_blocks_with(ciphertext, cipher,
                                      self._block_decryption_callback)
Beispiel #9
0
 def encrypt_with_cipher(self, plaintext, cipher):
     if type(plaintext) != BlockString:
         plaintext = BlockString(plaintext, self.block_size)
     plaintext = self._pad(plaintext)
     return self._iterate_blocks_with(plaintext, cipher,
                                      self._block_encryption_callback)
Beispiel #10
0
 def _iterate_blocks_with(self, block_string, cipher, callback):
     self.cipher = cipher
     self.block_string = block_string
     result = BlockString(block_size=self.block_size)
     return reduce(lambda _result, block: _result + callback(*block),
                   enumerate(self.block_string), result)