def test_challenge_15(self): expected = b'ICE ICE BABY' t1 = b'ICE ICE BABY\x04\x04\x04\x04' t2 = b'ICE ICE BABY\x05\x05\x05\x05' t3 = b'ICE ICE BABY\x01\x02\x03\x04' self.assertEqual(c9.pkcs7_unpad(t1), expected) with self.assertRaises(c9.PaddingError): c9.pkcs7_unpad(t2) with self.assertRaises(c9.PaddingError): c9.pkcs7_unpad(t3)
def mallory(to_alice, from_alice, to_bob, from_bob): """ Simulates the man-in-the-middle attack by sending bad values and decrypting the messages being passed. Args: to_alice: queue for sending messages to alice from_alice: queue for messages from alice to_bob: queue for sending messages to bob from_bob: queue for messages from bob """ # A->M Send p,g p, g = from_alice.get() # M->B Send p,g to_bob.put([p, g]) # B->A Send ACK to_alice.put(from_bob.get()) # A->M Send A A = from_alice.get() # M->B Send A to_bob.put(A) # B->M Send B B = from_bob.get() # M->A Send B to_alice.put(B) session_key = c33.make_session_key(g, 1, p) alt_session_key = c33.make_session_key(g, 2, p) key = session_key[0:16] alt_key = alt_session_key[0:16] # A->M Send AES-CBC(blah blah) msg = from_alice.get() dec_msgs = [] while msg: # M->B Relay to B to_bob.put(msg) ## Decrypt the message d_msg = b'' try: d_msg = c10.aes_128_cbc_decrypt(msg[16:], key, msg[0:16]) d_msg = c9.pkcs7_unpad(d_msg) except: d_msg = c10.aes_128_cbc_decrypt(msg[16:], alt_key, msg[0:16]) d_msg = c9.pkcs7_unpad(d_msg) dec_msgs.append(d_msg) to_alice.put(from_bob.get()) try: msg = from_alice.get(timeout=0.5) except: msg = False return dec_msgs
def bob(to_alice, from_alice): """ Simulates Bob's communication with Alice via DH. Bob decrypts the messages then sends them back after re-encrypting under a new IV. Args: to_alice: a queue for sending messages to alice from_alice: a queue for receiving messages from alice """ # A->B Send p,g,A p, g, A = from_alice.get() b, B = c33.diffie_hellman(p, g) # B->A Send B to_alice.put(B) session_key = c33.make_session_key(A, b, p) key = session_key[0:16] msg = from_alice.get(0.5) while msg: msg_iv = msg[0:16] msg = msg[16:] d_msg = c10.aes_128_cbc_decrypt(msg, key, msg_iv) d_msg = c9.pkcs7_unpad(d_msg) iv = os.urandom(16) d_msg = c9.pkcs7_pad( d_msg) # i know this weird but it does perform a check echo = c10.aes_128_cbc_encrypt(d_msg, key, iv) echo = iv + echo to_alice.put(echo) try: msg = from_alice.get(timeout=0.5) except: msg = False
def decode_profile(ct): """ Decodes the encrypted cookie and parses it into a dictionary. Args: ct: The encrypted cookie containing the profile information Returns: A dictionary containing the profile's information """ pt = AES.new(key, AES.MODE_ECB).decrypt(ct) return parse_cookie(c9.pkcs7_unpad(pt).decode("utf-8"))
def is_admin(cookie): """ Decryption oracle. Decrypts the cookie and searches for the admin token. Args: cookie: The encrypted cookie containing the user data Returns: True if the cookie contains ';admin=true;' """ data = c10.aes_128_cbc_decrypt(cookie, key) data = c9.pkcs7_unpad(data) return b';admin=true;' in data
def cbc_padding_attack(): """ Performs the CBC padding attack on the encryption oracle. Returns: The decrypted secret string. """ # The IV is given so we can get all blocks txt = iv + encryption_oracle() num_blocks = len(txt) // 16 result = b'' for i in reversed(range(1, num_blocks)): result = attack_block(txt, i) + result return c9.pkcs7_unpad(result)
def alice(to_bob, from_bob, msgs): """ Simulates Alice's communication to Bob with DH. Alice checks that the echo she receives back is the same as the message she sent. Args: to_bob: a queue for sending messages out to bob from_bob: a queue for receiving messages from bob msgs: list of messages to send to bob """ p = "0xffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024" p += "e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd" p += "3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec" p += "6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f" p += "24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361" p += "c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552" p += "bb9ed529077096966d670c354e4abc9804f1746c08ca237327fff" p += "fffffffffffff" p = int(p, 16) g = 2 a, A = c33.diffie_hellman(p, g) # A->B Send p,g,A to_bob.put([p, g, A]) # B->A Send B B = from_bob.get() session_key = c33.make_session_key(B, a, p) key = session_key[0:16] for msg in msgs: if DEBUG: print('Sending msg: ' + str(msg)) iv = os.urandom(16) e_msg = iv + c10.aes_128_cbc_encrypt(c9.pkcs7_pad(msg), key, iv) # A->B Send AES-CBC(key,msg,iv) + iv to_bob.put(e_msg) # B->A echo echo = from_bob.get() echo_msg = echo[16:] echo_iv = echo[0:16] d_echo = c10.aes_128_cbc_decrypt(echo_msg, key, echo_iv) d_echo = c9.pkcs7_unpad(d_echo) if DEBUG: print('Alice got echo: ' + str(d_echo)) assert d_echo == msg, d_echo
def decryption_oracle(txt): """ Decrypts the given ciphertext and determines if the padding is valid for it. Args: txt: The encrypted ciphertext Returns: True if the padding is valid. """ ct = c10.aes_128_cbc_decrypt(txt, key, iv) try: if DEBUG: print('Pad byte: ' + str(ct[-1])) ct = c9.pkcs7_unpad(ct) return True except: return False
def alice(to_bob, from_bob, msgs): """ Simulates Alice's communication to Bob with DH. Alice checks that the echo she receives back is the same as the message she sent. Args: to_bob: a queue for sending messages out to bob from_bob: a queue for receiving messages from bob msgs: list of messages to send to bob """ p = P g = G a, A = c33.diffie_hellman(p, g) # A->B Send p,g to_bob.put([p, g]) # B->A Send ACK ack = from_bob.get() assert ack == "ACK" # A->B Send A to_bob.put(A) # B->A Send B B = from_bob.get() session_key = c33.make_session_key(B, a, p) key = session_key[0:16] for msg in msgs: if DEBUG: print('Sending msg: ' + str(msg)) iv = os.urandom(16) e_msg = iv + c10.aes_128_cbc_encrypt(c9.pkcs7_pad(msg), key, iv) # A->B Send AES-CBC(key,msg,iv) + iv to_bob.put(e_msg) # B->A echo echo = from_bob.get() echo_msg = echo[16:] echo_iv = echo[0:16] d_echo = c10.aes_128_cbc_decrypt(echo_msg, key, echo_iv) d_echo = c9.pkcs7_unpad(d_echo) if DEBUG: print('Alice got echo: ' + str(d_echo)) assert d_echo == msg, d_echo
def test_challenge_10(self): pt = aes_128_cbc_decrypt(self.ctxt, self.key, self.iv) # To see the result, set DEBUG to true if self.DEBUG: print(c9.pkcs7_unpad(pt))
def test_challenge_12(self): self.assertEqual(get_blocksize(encryption_oracle), 16) self.assertTrue(is_ecb(encryption_oracle, 16)) secret = c9.pkcs7_unpad(decode_secret()) self.assertEqual(secret, unknown)
def test_challenge_14(self): actual = c9.pkcs7_unpad(decode_secret()) self.assertEqual(actual, unknown)