## Wednesday, March 13, 2013

### Backdoor CTF - Crypto 400

We have access to the code used for encryption function. With this we have to find the plain text value for the given cipher text:
```168 232 100 162 135 179 112 100 173 206 106 123 106 195 179 157 123 173
```
Encryption function:
```for (\$i = 0; \$i<strlen(\$str); \$i++)
\$dec_array[] = ord(\$str{\$i});
\$ar = \$dec_array;
\$max = max(\$ar);

\$key = rand(10,\$max);
\$key = 101*\$key;

for(\$i=0;\$i<strlen(\$str);\$i++){
\$x = \$ar[\$i];
\$am = (\$key+\$x)/2;
\$gm = sqrt(\$key*\$x);
\$enc = \$am + \$gm;
\$encrypt = floor(\$enc)%255;
echo \$encrypt.' ';
}
```
Bruteforce seemed to be the easiest solution for the problem. Here is the approach
[*] Key value is choosen from rand(10,\$max), where \$max to range from 32 to 127 ie ascii printables. So we can bruteforce key value between 10 to 127
[*] Choose plain text values between 32 to 127 and perform encryption function upto the length of cipher text
[*] Check if any of key value results in count(plain text) == count(cipher text). In that case, the string we got might be the possible plain text

Here is the code to do that:
```<?php

\$cipher = array(168, 232, 100 ,162, 135, 179, 112, 100, 173, 206, 106, 123, 106, 195, 179, 157, 123, 173);

for(\$key=10; \$key<=127; \$key++){
\$plain = array();
\$key_new = \$key * 101;
for(\$i=0; \$i<count(\$cipher); \$i++){
for(\$p=32; \$p<=127; \$p++){
\$x = \$p;
\$am = (\$key_new+\$x)/2;
\$gm = sqrt(\$key_new*\$x);
\$enc = \$am + \$gm;
\$encrypt = floor(\$enc)%255;
if(\$encrypt == \$cipher[\$i])
array_push(\$plain,\$p);
}
}
if(count(\$plain) == count(\$cipher)){
\$text = '';
foreach(\$plain as \$t)
\$text = \$text.chr(\$t);
echo \$text."\n";
}
}

?>
```
```[ctf@renorobert backdoor]# php sol.php
, f&." -i!W!Wo.*-i
myalgocantbebroken
```
Running the code we get two plain texts. The real plain text value is myalgocantbebroken