def c9(): block_size = 20 msg = b"YELLOW SUBMARINE" padded_message = pkcs7_pad(msg, block_size) expected_padded_message = b"YELLOW SUBMARINE\x04\x04\x04\x04" print("S2C9 padded message correct: {}", padded_message == expected_padded_message)
def c13(): block_size = 16 secret_key = get_random_bytes(block_size) def encryptor(email_address): return aes128_ecb_encode( secret_key, pkcs7_pad(c13_profile_for(email_address), block_size)) def decryptor(cipher_text): return c13_parse_kv( pkcs7_unpad(aes128_ecb_decode(secret_key, cipher_text), block_size)) # The minimum amount of prefix padding to cause a duplicated block # will give us the target block in the next block for repeat_pad_size in range(2 * block_size - 1, 3 * block_size): repeat_pad = b"A" * repeat_pad_size trick_email_address = repeat_pad + pkcs7_pad( b"admin", block_size) + b"@example.com" cipher_text = encryptor(trick_email_address) chunks = chunk(cipher_text, block_size) # If we have a repeat, the block after repeat is target next_is_target = False target_cipher_block = b'' last_chunk = b'' for c in chunks: if next_is_target: target_cipher_block = c break next_is_target = (c == last_chunk) last_chunk = c if target_cipher_block != b'': break if target_cipher_block == b'': raise RuntimeError("Didn't find target cipher block") # At some padding between 0..block_size the end block should # be 'user<pkcspadding>'. If so, replacing it with our # target cipher block should give us something which will decode # to our desired plaintext for padding_size in range(0, block_size): padded_email_address = (b"A" * padding_size) + b"@example.com" cipher_text = encryptor(padded_email_address) # Splice in target block cipher_text = bytearray(cipher_text) cipher_text[-block_size:] = target_cipher_block cipher_text = bytes(cipher_text) try: profile = decryptor(cipher_text) if profile[b"role"] == b"admin": print("S2C13 - did it! got an admin role") return except (KeyError, ValueError): pass print("S2C13 fail. Bad coder, no biscuit")
def encryption_oracle(data): prepad = Random.get_random_bytes(random.choice(range(5, 11))) postpad = Random.get_random_bytes(random.choice(range(5, 11))) padded = pkcs7_pad(prepad + data + postpad) key = keygen() if random.choice(range(2)) == 0: iv = keygen() return cbc_encrypt(data, key, iv) else: return ecb_encrypt(data, key)
def c12_encryption_oracle(key, chosen_plain_text): block_size = 16 secret_suffix = b64decode( """Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg YnkK""") msg = pkcs7_pad(chosen_plain_text + secret_suffix, block_size) return aes128_ecb_encode(key, msg)
def c11_encrypt_ecb_or_cbc_oracle(plain_text): block_size = 16 key = get_random_bytes(block_size) prefix = get_random_bytes(10) suffix = get_random_bytes(10) msg = pkcs7_pad(prefix + plain_text + suffix, block_size) if random.random() >= 0.5: print("S2C11 - doing CBC") iv = get_random_bytes(16) return aes128_cbc_encode(key, iv, msg) else: print("S2C11 - doing ECB") return aes128_ecb_encode(key, msg)
def encrypt(self, plainText): blockCount = int(len(plainText) / self.blocksize) + 1 # pad plaintext plainTextBytes = bytearray(pkcs7_pad(plainText, self.blocksize).encode('utf-8')) # generate random block last_block = createRandomBlock(self.blocksize) result = last_block for blockIndex in reversed(range(0, blockCount)): startByte = (blockIndex * self.blocksize) endByte = startByte + self.blocksize currentBlock = plainTextBytes[startByte:endByte] last_block = self.encryptBlock(currentBlock, last_block) result = last_block + result return result
def c17_encryptor(block_size, key, iv): target_b64_strings = [ "MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=", "MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=", "MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==", "MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==", "MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl", "MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==", "MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==", "MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=", "MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=", "MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93", ] b64_string = choice(target_b64_strings) plain_text = b64decode(b64_string) padded_plain_text = pkcs7_pad(plain_text, block_size) return aes128_cbc_encode(key, iv, padded_plain_text)
def c14_encryption_oracle(key, chosen_plain_text): block_size = 16 secret_suffix = b64decode( """Um9sbGluJyBpbiBteSA1LjAKV2l0aCBteSByYWctdG9wIGRvd24gc28gbXkg aGFpciBjYW4gYmxvdwpUaGUgZ2lybGllcyBvbiBzdGFuZGJ5IHdhdmluZyBq dXN0IHRvIHNheSBoaQpEaWQgeW91IHN0b3A/IE5vLCBJIGp1c3QgZHJvdmUg YnkK""") prefix_size = randrange(20, 40) random_prefix = get_random_bytes(prefix_size) msg = random_prefix + chosen_plain_text + secret_suffix # chunk_index = 0 # chunks = chunk(msg, 16) # for c in chunks: # chunk_index+= 1 # print("JB - oracle pt {}/{}: [{}]".format(chunk_index, len(chunks), c)) msg = pkcs7_pad(msg, block_size) return aes128_ecb_encode(key, msg)
def main(): print "\n---------- Start of Padding Oracle Attack ----------\n" plaintext = raw_input("Enter your plaintext WITHOUT padding: ") oracle = Oracle(KEY, BLOCK_SIZE) padded_plaintext = pkcs7_pad(plaintext, BLOCK_SIZE) ciphertext = oracle.aes_padding(padded_plaintext, IV) print "\nPlaintext Entered: {} Number of bytes: {}".format( plaintext, len(plaintext)) print "Padded Plaintext: {} Number of bytes: {}".format( padded_plaintext, len(padded_plaintext)) print "Ciphertext: {} Number of bytes: {}\n".format( repr(ciphertext), len(ciphertext)) print "Executing attack..." decoded_ciphertext = execute_padding_oracle_attack(oracle, ciphertext, IV) print "Attack has ended.\n" print "Decoded Ciphertext: {} Number of bytes: {}".format( decoded_ciphertext, len(decoded_ciphertext)) print "\n---------- End of Padding Oracle Attack ----------\n"
def c16_encryptor(block_size: int, key, iv, plain_text): buf = hexquote_chars(b";=", plain_text) buf = b"comment1=cooking%20MCs;userdata=" + buf + b";comment2=%20like%20a%20pound%20of%20bacon" padded_buf = pkcs7_pad(buf, block_size) return aes128_cbc_encode(key, iv, padded_buf)
def encryptor(email_address): return aes128_ecb_encode( secret_key, pkcs7_pad(c13_profile_for(email_address), block_size))
from util import pkcs7_pad data = 'YELLOW SUBMARINE' print data.encode('hex') print pkcs7_pad(data, 20).encode('hex')