Rating:

We start by observing that there are two classes of possible responses. If we submit the given cookie, it gives Nop. :( or Don't be rude!. If we submit a random hex string, it gives That cookie looks burned!. This suggests a potential padding oracle attack. Typically, a padding oracle attack is used to decrypt messages, but in this case we use it to encrypt.

We start by looking at how AES-CBC decryption works.![](https://defuse.ca/images/cbc_decryption.png)

Let $C_n$ be the nth ciphertext block. Let $P_n$ be the nth plaintext block. Let $D$ be the AES decryption function.
We see that $P_n = D(C_n) \oplus C_\{n-1\}$ This means that we can control $P_n$ by selecting $C_\{n-1\} = D(C_n) \oplus P1_n$, where $P1_n$ is the desired plaintext. However, this means we have to determine $D(C_n)$.

Next, we have to understand how PKCS #7 padding works. Let's assume the block size is 16 bytes, and the last block of plaintext is only 9 bytes long. We pad the remaining 7 bytes with the hex of the number of bytes remaining, 07, which becomes 07 07 07 07 07 07 07. If the last block of plaintext is exactly 16 bytes, we still need to add padding to signal that the previous block is unpadded. In this case, we append a block of 16 null bytes.

If a program gives a different output when this padding is wrong, then we can use that to get $D(C_n)$.

Let $A[i]$ be the ith byte of A.
We start by sending a 2 block message, a block of null bytes and the $C_n$ we want to decrypt. The first block will be treated as the IV, and the second block will be decrypted and xored with the IV.
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 $\oplus$ $D(C_n)$

The only way this could have correct padding is if $D(C_n)[16] \oplus IV[16]$ has a last byte of 01 (or 02 02, etc... but these are rare). Then we have determined the last byte of $D(C_n)$, since $D(C_n)[16] \oplus IV[16] = 1$, $D(C_n)[16] = IV[16] \oplus 1 = 0 \oplus 1 = 1$

Otherwise, we increment the last byte of the IV.

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 $\oplus$ $D(C_n)$

Again, if this has correct padding, we have determined the last byte of $D(C_n)$, since $D(C_n)[16] \oplus IV[16] = 1$, $D(C_n)[16] = IV[16] \oplus 1 = 1 \oplus 1 = 0$

In general, we continue incrementing the last byte of IV until we get correct padding.

Once we get the last byte of $D(C_n)$, we can extend this process to get the second last byte.

First, we select the last byte of $IV$ such that $D(C_n)[16] \oplus IV[16] = 2$, which simply means $IV[16] = 2 \oplus D(C_n)[16]$.

Again, if this has correct padding, it means that $D(C_n)[15] \oplus IV[15] = 2$, as 02 02 would be the only valid padding here. Using similar logic as before, we continue incrementing $IV[15]$ until we have correct padding and then determine $D(C_n)[15]$. We can then repeat this whole process for every byte until we have $D(C_n)$. We can then select $C_\{n-1\} = D(C_n) \oplus P1_n$.

Combining all of this, we can create our exploit. We start by creating a random block of 16 bytes which will be our $C_n$. We select a $C_\{n-1\}$ such that $P_n$ is what we desire. We repeat this process to find a $C_\{n-2\}$, etc... until we reach $C_1$. That block will be our IV. We append all blocks together to get a ciphertext that decrypts to the desired plaintext, in this case, Maple Oatmeal Biscuits, and submit to get the flag.