While doing observing of Amerikanski’s voting infrascture we find interesting box. We send operative to investigate. He return with partial input like showing below. He say box very buggy but return encrypted data sometimes. Figure out what box is do; maybe we finding embarass material to include in next week bitcoin auction, yes?
In addition to this description, the Russian spy was also able to exfil a transmission snippet which when reconstructed looks like this:
If we send this to the server, we get back a response that remote debugging enabled along with an error:
Now we know that the remote debugging mode allows to leak information about the program itself. If we add a field for the key of the appropriate length (16 bytes), the server responds with:
Now that we have a basic idea of what the server expects from us, we can manipulate the program to crash at different points in the execution. Since the program gives us the error traceback, we can use this to reconstruct the program source.
For instance, if we give the data as a list with the same length as the key instead of a string, we learn that the data is being encrypted with CBC:
And if we make the list shorter, we get another error which leaks information about how the plaintext is padded.
After several more of these leaks, most of the source code is recovered:
After reconstructing the source, it was still unclear what we were actually trying to discover. After toying with some requests for a litter longer, I realized that the if the debug field is removed, the encryption key is ignored and that the ciphertext is longer than it should be.
Because of this, we know that the server is likely appending extra information – probably the flag!
Breaking the Cipher
From the source code, we know that the server is using a custom implementation of AES CBC. Additionally, because the same data encrypted multiple times yields identical ciphertexts, we know that a fixed IV is being used. Unlike ECB, CBC mode is usually not vulnerable to byte by byte decryption. However, the constant IV allows for this kind of attack.
The idea of a byte by byte decryption is to give the server the blocksize - 1 known bytes to encrypt so that the full plaintext is:
Now the first block of encrypted message is made up of A’s and the first byte of the flag. Using this fact, we can brute force the first byte of the flag by sending the same number of A’s and all possible values for the byte and checking if the first block of the ciphertexts match.
We can continue this process until we recover all the bytes of the flag.