Note: this article uses MathJax to display formulas written in TeX. Please
enable Javascript in order to see the formulas correctly.

Web 400 was an interesting challenge involving web exploits as well as crypto.
We had access to a web application which allowed sending messages from a user
to another. The twist is that all of these messages were encrypted using an
unknown algorithm. When sending a message the user provides a key which is used
to encrypt the message.

After analyzing the algorithm a bit (same key and message, trying different key
sizes and block sizes, checking if every block is encrypted the same, etc.) we
found out that it was some kind of ECB XOR using the key + a constant 64 bits
value. This was only true for the first few blocks though: after that another
key or another constant value was used. As we'll soon see, this does not matter
a lot.

We were able to confirm that this message system is vulnerable to XSS attacks
by sending some strings that give HTML tags when encrypted. We just need to
encode a cookie stealer and send it to the admin user to gain access to his
account.

Now that we know this algorithm uses XOR as its main operation, we can use a
very interesting property of this binary operator:

If we send a block using a plaintext P1 and it gives us C1, we can use that
property to deduce what we should send to have C2 be what we want:

$$P2 = C2 \oplus Key \Rightarrow P2 = C2 \oplus (P1 \oplus C1)$$

It turns out we can't use that for a whole message because the key seems to
depend on the previous blocks plaintexts. We had to construct the message block
per block using that technic. When encrypted, our message is:

We sent that to the admin and got his session ID transmitted to our server.
Using that we were able to login to his account and find some encrypted
messages (and their associated key). The first message had a plaintext key when
decrypted gave us another encryption key, which we used to decrypt a second
message, giving us the final key we had to submit on the CTF website.