I recovered the flag in multiple parts.
The first 7 bytes of the were known: hitcon{
The text (pad('Welcome!!')
) was encrypted and sent, this known plaintext-ciphertext pair could be used to produce the encryption of any 1-block message by xoring the IV, I used this to send the get-flag
command. Then I could brute-force the first block of the flag byte-by-byte by modifying this message so its decryption starts with a number of spaces and the get-flag
command if I could guess the next character correctly. (The get-flag
command is 8 bytes and 7 bytes of the flag was already known, so I could start with the 8th). This gave me the first block of the flag: hitcon{Paddin9_1
The next 8 bytes were recovered with a different strategy. I changed the encrypted flags' first block to contain ' '*9+'get-md5'
and appended a random extra block to its end. When the server decrypted it the random ending block produced a random padding, so in good cases the stripped command looked like 'get-md5' + someprefixof(flag[16:])
. I repeated it with lots of different random blocks so I get the encrypted hashes of all the flag's second block's prefixes. Then I could brute-force the next 8 bytes one-by-one by sending the pad('get-md5'+guessedflagprefix)
messages' encryption. After this I knew the first 24 bytes of the flag: hitcon{Paddin9_15_ve3y_h
The rest of the second block was recovered exactly as the end of the first block. This gave me the first 32 bytes: hitcon{Paddin9_15_ve3y_h4rd__!!}
. I hoped there are no more characters so I submitted it and got the points.