Exemple #1
0
def parameter_injection_attack(alice, bob):
    """Simulates a MITM key-fixing attack on Diffie-Hellman with parameter injection."""

    # Step 1: Alice computes A and sends it to the MITM (thinking of Bob)
    A = alice.get_public_key()

    # Step 2: the MITM changes A with p and sends it to Bob
    A = alice.p

    # Step 3: Bob computes B and sends it to the MITM (thinking of Alice)
    B = bob.get_public_key()

    # Step 4: the MITM changes B with p and sends it to Alice
    B = bob.p

    # Step 5: Alice finally sends her encrypted message to Bob (without knowledge of MITM)
    _msg = b'Hello, how are you?'
    _a_key = unhexlify(sha1(str(alice.get_shared_secret_key(B)).encode()))[:16]
    _a_iv = Random.new().read(AES.block_size)
    a_question = aes_cbc_encrypt(_msg, _a_key, _a_iv) + _a_iv

    # Step 6: the MITM relays that to Bob

    # Step 7: Bob decrypts the message sent by Alice (without knowing of the attack), encrypts it and sends it again
    _b_key = unhexlify(sha1(str(bob.get_shared_secret_key(A)).encode()))[:16]
    _a_iv = a_question[-AES.block_size:]
    _a_message = aes_cbc_decrypt(a_question[:-AES.block_size], _b_key, _a_iv)
    _b_iv = Random.new().read(AES.block_size)
    b_answer = aes_cbc_encrypt(_a_message, _b_key, _b_iv) + _b_iv

    # Step 8: the MITM relays that to Alice

    # Step 9: the MITM decrypts the message (either from a_question or from b_answer, it's the same).
    #
    # Finding the key after replacing A and B with p is, in fact, very easy.
    # Instead of (B^a % p) or (A^b % p), the shared secret key of the exercise became (p^a % p)
    # and (p^b % p), both equal to zero!
    mitm_hacked_key = unhexlify(sha1(b'0').encode())[:16]

    # Hack Alice's question
    mitm_a_iv = a_question[-AES.block_size:]
    mitm_hacked_message_a = aes_cbc_decrypt(a_question[:-AES.block_size],
                                            mitm_hacked_key, mitm_a_iv)

    # Hack Bob's answer (which here is the same)
    mitm_b_iv = b_answer[-AES.block_size:]
    mitm_hacked_message_b = aes_cbc_decrypt(b_answer[:-AES.block_size],
                                            mitm_hacked_key, mitm_b_iv)

    # Check if the attack worked
    assert _msg == mitm_hacked_message_a == mitm_hacked_message_b
Exemple #2
0
    def encrypt(plaintext):
        # Add a random padding before and after the plaintext
        padded_plaintext = AesEncryptionOracle._pad_with_bytes(plaintext)

        # Generate a random key
        key = Random.new().read(block_size)

        # Encrypt randomly with ECB or CBC
        if randint(0, 1) == 0:
            return "ECB", aes_ecb_encrypt(padded_plaintext, key)
        else:
            return "CBC", aes_cbc_encrypt(padded_plaintext, key,
                                          Random.new().read(block_size))
Exemple #3
0
 def get_encrypted_message(self):
     """Selects at random one of the 10 input strings and encrypts it under a random key and IV with AES-128-CBC."""
     chosen_input = self._possible_inputs[randint(
         0,
         len(self._possible_inputs) - 1)].encode()
     return aes_cbc_encrypt(chosen_input, self._key, self.iv)
Exemple #4
0
 def encrypt(self, data):
     """Adds the prefix and the suffix specified in the challenge and encrypts the data with AES-128-CBC"""
     data = data.replace(';', '').replace(
         '=', '')  # Remove special characters to avoid injection
     plaintext = (self._prefix + data + self._suffix).encode()
     return aes_cbc_encrypt(plaintext, self._key, self._iv)
Exemple #5
0
def malicious_g_attack():
    """Simulates the break of Diffie-Hellman with negotiated groups by using malicious 'g' parameters."""
    p = DiffieHellman.DEFAULT_P

    for g in [1, p, p - 1]:

        # Step 1: the MITM changes the default g sent by Alice to Bob with a forced value
        alice = DiffieHellman()
        bob = DiffieHellman(g=g)

        # Step 2: Bob receives this forced g and sends an ACK to Alice

        # Step 3: Alice computes A and sends it to the MITM (thinking of Bob)
        A = alice.get_public_key()

        # Step 4: Bob computes B and sends it to the MITM (thinking of Alice)
        B = bob.get_public_key()

        # Step 5: Alice sends her encrypted message to Bob (without knowledge of MITM)
        _msg = b'Hello, how are you?'
        _a_key = unhexlify(sha1(str(
            alice.get_shared_secret_key(B)).encode()))[:16]
        _a_iv = Random.new().read(AES.block_size)
        a_question = aes_cbc_encrypt(_msg, _a_key, _a_iv) + _a_iv

        # Step 6: Bob receives the message sent by Alice (without knowing of the attack)
        # However, this time Bob will not be able to decrypt it, because (if I understood the
        # challenge task correctly) Alice and Bob now use different values of g.

        # Step 7: the MITM decrypts the Alice's question
        mitm_a_iv = a_question[-AES.block_size:]

        # When g is 1, the secret key is also 1
        if g == 1:
            mitm_hacked_key = unhexlify(sha1(b'1').encode())[:16]
            mitm_hacked_message = aes_cbc_decrypt(a_question[:-AES.block_size],
                                                  mitm_hacked_key, mitm_a_iv)

        # When g is equal to p, it works the same as in the S5C34 attack (the secret key is 0)
        elif g == p:
            mitm_hacked_key = unhexlify(sha1(b'0').encode())[:16]
            mitm_hacked_message = aes_cbc_decrypt(a_question[:-AES.block_size],
                                                  mitm_hacked_key, mitm_a_iv)

        # When g is equal to p - 1, the secret key is (-1)^(ab), which is either (+1 % p) or (-1 % p).
        # We can try both and later check the padding to see which one is correct.
        else:

            for candidate in [str(1).encode(), str(p - 1).encode()]:
                mitm_hacked_key = unhexlify(sha1(candidate).encode())[:16]
                mitm_hacked_message = aes_cbc_decrypt(
                    a_question[:-AES.block_size],
                    mitm_hacked_key,
                    mitm_a_iv,
                    unpad=False)

                if is_pkcs7_padded(mitm_hacked_message):
                    mitm_hacked_message = pkcs7_unpad(mitm_hacked_message)
                    break

        # Check if the attack worked
        assert _msg == mitm_hacked_message