I tend to skip crypto challenges involving a telnet-style service as it feels like too much work, but this time I used the chance to try out pwntools. Some confusing behavior aside it's pretty nice for this purpose. The server sends out some hex string, then enters a loop of accepting user input, processing it and printing the resulting hex string. I spent way too much time on studying the first hex string printed before that loop, this turned out to be a dead end. Studying the user input loop I've observed the following: - If you enter "flag{", in some sessions the output matches up with the initial line of hex. - If you enter the same character often the blocks repeat. - The block size appears to be 32 hex chars (or 16 bytes). - The repeating blocks are in the middle, suggesting that there's random text inserted before and after user input, then encrypted in ECB mode. This means that the challenge is the same as Cryptopals #14. I've solved that one by doing the following: - Determining the length of the random prefix. For this I've submitted user input consisting of the same character repeated 32 times, checked whether the output has duplicate blocks. If not, add one more character and repeat the test. Eventually there will be duplicate blocks, the length of the prefix can then be calculated from the position of the duplicate block and the user input length. - Determining the length of the random suffix. ECB-encrypted input is padded to a multiple of the block size, with the padding being at most as large as a block. Using a similar algorithm as for the previous step user input is increased starting with 16 chars until the output string gains an extra block of chars. Using the output, input and prefix length the suffix length can then be calculated. - Determining the "glue size", that is the amount of user input required so that the combination of random prefix and user input lines up with a block. - Knowing these parameters every suffix byte can be decoded by crafting block-sized user input short of one suffix byte which is filled in by the server for us, then obtaining the corresponding encrypted block. - Then user inputs are submitted that look the same as that user input plus a possible suffix byte and the resulted encryption block is compared against the previously determined one. - If they match up, the suffix byte has been successfully guessed and the process is repeated with an even shorter input block and the guessed bytes so far. - One noteworthy optimization is trying the bytes in the ASCII range in reverse order, that saves like 30s for each round. The script eventually spits out the following suffix: flag{y0u_kn0w_h0w_B10cks_Are_n0T_r31iab13...}