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 decrypt_and_check_admin(self, ciphertext):
        """Decrypts the ciphertext and: if the decrypted message is not ASCII compliant, raises an exception 
        and returns the bad plaintext; otherwise returns whether the characters ";admin=true;" are in the string.
        """
        plaintext = aes_cbc_decrypt(ciphertext, self._key, self._iv)

        if not check_ascii_compliance(plaintext):
            raise Exception("The message is not valid", plaintext)

        return b';admin=true;' in plaintext
Exemple #3
0
 def decrypt_and_check_padding(self, ciphertext, iv):
     """Decrypts the given ciphertext with the given IV and with the random key generated before
     by the encryption oracle. Returns True if the decrypted plaintext is pkcs7 padded correctly.
     """
     plaintext = aes_cbc_decrypt(ciphertext, self._key, iv, False)
     return is_pkcs7_padded(plaintext)
Exemple #4
0
 def decrypt_and_check_admin(self, ciphertext):
     """Decrypts the string and returns whether the characters ";admin=true;" are in the string"""
     data = aes_cbc_decrypt(ciphertext, self._key, self._iv)
     return b';admin=true;' in data
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