Tags: crypto
Rating:
We are presented with a login system that simply encrypts a JSON blob under AES-CBC, without performing any integrity checks on the data. As such, it is subject to manipulation. Additionally, we have an encryption oracle in the form of a registration script, allowing us to generate a ciphertext of the following form:
{"username":"OUR_USERNAME"}
The only restriction is that OUR_USERNAME cannot be "admin".
Decryption of AES-CBC ciphertext involves decrypting each block of ciphertext with AES, then performing an XOR operation between the AES-decrypted block and the previous block of ciphertext. For the first block, there is no previous ciphertext block and as such the Initialization Vector (IV), a random block-sized piece of data, is used. Wikipedia has a nice diagram of the process:
When flipping any bit in any block of the ciphertext, it effectively randomizes the decryption of that block. When performing edits to CBC-mode ciphertext, we must either change bits in a block whose meaning is relatively unimportant or, if we have control of the IV, we can modify it to change the first block without any repercussions. Luckily, we do have control of the IV!
We know that the message will take the following form: {"username":"admin"}
As such, we can guess that the first two bytes of the username will be at the end of our first block. This means we just need to register a username with one bit off from admin and then flip the bits of the resulting authentication cookie until we get access to /admin. Flipping the least significant bit of a (0x61) gives us ` (0x61). We register `dmin and then use Burp Intruder to flip the bits like so:
Once we flip the least significant bit of the second to last byte of the IV, we change the username in our ciphertext from "`dmin" to "admin", which gives us access to the admin section, containing the following message:
Note to self - my password is CTF{lettuce.3njoy.our.f00d.puns}