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.