For this challenge we can connect to a server and use the following commands:

encrypt - Encrypt with AES
flag - Encrypt flag
getkey - Set AES key
help - show this help
setkey - Set AES key

When we call the “flag” command a new random key will be set and it will be used to encrypt the flag. Clearly we can think of calling the “flag” command, then the “getkey” and simply decrypt the flag. Unfortunately this does not work as we can see from this log:

Welcome to the online AES encryption service
setkey 41414141414141414141414141414141
encrypt 414243444546

When I saw this I just thought “WTF?!”. Apparently after the first encryption the key is changed! After some research we found out that the key we got after the first encryption was the result of the AES Key Expansion.

We therefore had to write a function that gives us back the original master key from the derived key and use it to decrypt the flag. Luckily we found a mathematical representation of this invert function:

K(i-1, 4) = K(i, 3) XOR K(i, 4)

K(i-1, 3) = K(i, 2) XOR K(i, 3)

K(i-1, 2) = K(i, 1) XOR K(i, 2)

K(i-1, 1) = K(i, 1) XOR sub(shift(K(i-1, 4)) XOR RCON(i)

This script automates it all and gives back the flag :)