Decrypt this “UPDYUFFRPY\TDDSUITF\R\FARTTITYGPPF\/YSGDFY
AAO:DF/TA\IAGR:A//DR/T”.
ctf.ifmo.ru:5555
If we connect to the service and try to encrypt \x00, \x01, \x02, \x03, \x04, we can notice that only first two bytes and the last one change:
[ GDOPU/SIIR\TDPAFYGDA/:S/EIT\\FS/OA:PRYS/DOIOTIS/GUPPYPS/GIGPUSS\ ]
[ GFOPU/SIIR\TDPAFYGDA/:S/EIT\\FS/OA:PRYS/DOIOTIS/GUPPYPS/GIGPUSSE ]
[ GGOPU/SIIR\TDPAFYGDA/:S/EIT\\FS/OA:PRYS/DOIOTIS/GUPPYPS/GIGPUSSR ]
[ ::OPU/SIIR\TDPAFYGDA/:S/EIT\\FS/OA:PRYS/DOIOTIS/GUPPYPS/GIGPUSST ]
There are 16 different chars, so a good idea is to replace them with [0-9a-f]. GD->GF->GG->::->:/ – looks like it’s increasing by 1 each step. That means, that ‘::’ is ’00’ ;) Make some more encryptions and we get a charset: “:/\ERTYUIOPASDFG” -> “0123456789abcdef”.
I wrote a simple decoder:
<?php $alpha = str_split(":/\\ERTYUIOPASDFG", 1); $replace = str_split("0123456789abcdef", 1); fgets(STDIN); fgets(STDIN); $s = fgets(STDIN); $s = str_replace($alpha, $replace, $s); echo $s; ?>
Use it like:
$ echo -e "\x04\x00\x00\x00" | nc ctf.ifmo.ru 5555 | php client.php [ 009a71c88425dabe6fdb10c138522ec19b0a46c1d98958c1f7aa6ac1f8fa7cc5 ]
A fact that the byte is increased along with the input, points that it is a sum of input and some value. Let’s modify a client to get true values:
$ python -c 'print "\x00"*32;' | nc ctf.ifmo.ru 5555 | php client.php [ fc9a71be7a25dabe6fdb10c138522ec19b0a46c1d98958c1f7aa6ac1f8fa7cc1 ]
<?php $alpha = str_split(":/\\ERTYUIOPASDFG", 1); $replace = str_split("0123456789abcdef", 1); fgets(STDIN); fgets(STDIN); $s = fgets(STDIN); $s = str_replace($alpha, $replace, $s); $ss = str_split(substr($s, 2, -3), 2); $as = str_split("fc9a71be7a25dabe6fdb10c138522". \ "ecba50a46c1d98958c1f7aa6ac1f8fa7cc1", 2); $s = ''; foreach ($as as $index=>$add) { $char = hexdec($ss[$index])-hexdec($as[$index]); $t = dechex($char & 0xff); while (strlen($t)<2) $t = "0$t"; $s .= $t; } echo "[ $s ]\n"; ?>
Now, let’s play with encryption a bit more to understand it. Some tries and we understand that each byte is xored by next:
\xcc\x0c\x00\x00 -> \xc0\x0c\x00\x00
It’s time to write a decrypter:
<?php $s = "UPDYUFFRPY\\TDDSUITF\\R\\FARTTITYGPPF\\/Y". \ "SGDFYAAO:DF/TA\\IAGR:A//DR/T"; $alpha = str_split(":/\\ERTYUIOPASDFG", 1); $replace = str_split("0123456789abcdef", 1); $s = str_replace($alpha, $replace, $s); $ss = str_split( $s, 2); $as = str_split("fc9a71be7a25dabe6fdb10c13852". \ "2ec19b0a46c1d98958c1f7aa6ac1f8fa7cc1", 2); $s = ''; $ts = array(); foreach ($as as $index=>$add) { $char = hexdec($ss[$index])-hexdec($as[$index]); $t = dechex($char & 0xff); while (strlen($t)<2) $t = "0$t"; $ts[] = $t; } $rev = ''; for ($i = count($ts); $i > 0; $i--) { $c = hexdec($ts[$i-1]); $c ^= hexdec($ts[$i % 32]); $t = dechex($c & 0xff); while (strlen($t)<2) $t = "0$t"; $ts[$i-1] = $t; $rev = chr($c).$rev; } echo $rev."\n"; ?>
$ php solve.php *TheCoolestFlagOverTheWorldEver* $ echo "*TheCoolestFlagOverTheWorldEver*" | nc ctf.ifmo.ru 5555 Enter the text to encrypt: > Encryption successful: [ UPDYUFFRPY\TDDSUITF\R\FARTTITYGPPF\/YSGDFYAAO:DF/TA\IAGR:A//DR/T ]
You can find the binary here.