0
$\begingroup$

I am currently trying to solve a training challenge based on AES with CBC. This is the infos I'm given:

KEY = "yn9RB3Lr43xJK2██".encode()
IV  = "████████████████".encode()
msg = "AES with CBC is very unbreakable".encode()

Those spaces are unknown characters, and I also have the output:

c5██████████████████████████d49e78c670cb67a9e5773d696dc96b78c4e0

Does anyone have any idea on where I can start? My idea would be to bruteforce the key since only 2 characters are missing but I don't know how can I do it.

Note that the output was produces via the following python code:

aes = AES.new(KEY, AES.MODE_CBC, IV)
print binascii.hexlify(aes.encrypt(msg)).decode()

Edit:

from Crypto.Cipher import AES
import binascii
from pwn import xor
from Crypto.Util.number import bytes_to_long

alphabet = [chr(i) for i in range(31,128)]
key_base = b"yn9RB3Lr43xJK2"
iv = ""
output = b'c500000000000000000000000000d49e78c670cb67a9e5773d696dc96b78c4e0'
output_bytes = binascii.unhexlify(output)

msg = "AES with CBC is very unbreakable".encode()

for char1 in alphabet:
    for char2 in alphabet:
        key = key_base + char1.encode() + char2.encode()
        aes = AES.new(key, AES.MODE_CBC)
        decryptedMsg = aes.decrypt(output_bytes)
        if decryptedMsg[16] == msg[16] and decryptedMsg[31] == msg[31] and decryptedMsg[30] == msg[30]:
            print(key)
            cipher_1 = xor(msg[16:], decryptedMsg[16:])
            iv = xor(aes.decrypt(cipher_1), msg[:16])
            #print(AES.new(key, AES.MODE_CBC, iv).encrypt(msg[:16]) == cipher_1)
            
            # Now let's verify if we got the correct value or not..
            aes = AES.new(key, AES.MODE_CBC, iv)
            print(binascii.hexlify(aes.encrypt(msg)).decode()) #This value should correspond to output_bytes
$\endgroup$
8
  • 2
    $\begingroup$ Hint: there are three bytes of the first ciphertext block that are known. That means that you can block-decrypt the second block and compare those bytes with the plaintext (after the required bit-operation). As you are only missing two bytes from the key it is likely that there is only one solution that fits. $\endgroup$
    – Maarten Bodewes
    Jul 23 at 17:24
  • $\begingroup$ I've had a look at how AES CBC works but I've not quite understood the relationship between the output string and the first cipherblock, how can I deduct which bytes to use starting from the cipher? $\endgroup$
    – Shark44
    Jul 23 at 18:04
  • $\begingroup$ So the ciphertext bytes of the first block are XOR'ed with the plaintext bytes before encryption. When decrypting you go the other way around, starting with a block decrypt of the second block. So you can then use these known bytes of block 1 to retrieve the plaintext of block 2 by using the "opposite of XOR". If those bytes match then you have a key that could have been used for encryption - and as there are only 65ki possible key candidates, that's probably the key you need (going over the entire key space would be wise, there may be two, but that would probably invalidate the CTF, so). $\endgroup$
    – Maarten Bodewes
    Jul 23 at 18:24
  • $\begingroup$ Hint 2: You could significantly shorten the development of your program by filling in any value, say 0x00, for the unknown bytes, perform "a decryption operation" and then compare bytes. $\endgroup$
    – Maarten Bodewes
    Jul 23 at 18:28
  • $\begingroup$ Wouldn't I need the IV as well to perform the XOR to "check" whether the key is correct or not? I am not understanding how you refer to the first/second block, how do you retrieve them from the output string? $\endgroup$
    – Shark44
    Jul 23 at 18:48

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.