To access “Level 3” of the NcN CTF we first need to download the file (level.elf) the server offers. Running the program for the first time shows the following output:
The binary waits for user input. After pressing one key, it denies access with the message “I DON’T THINK SO”. Maybe we need to press another key to that one I pressed before. I tried all keys and finally got this result when pressing “SPACE”.
It displays an additional star to indicate that our first character (SPACE) was right. Pressing SPACE again leads to program failure again. What we need to do is just gaining the full passphrase. This can be achieved by brute forcing it – the same way we found the first character – or by analyzing the binary code.
A first look into the assembler code of the binary shows some obfuscation inside. So I decided that brute forcing the key will be much faster. The following PERL Script does the job for us:
#!/usr/bin/perl -w $found = $ARGV[0]; for ($i = 0x20; $i<=0x7f; $i++) { $try = $found . chr($i); print "TRYING: $try ($i)\n"; open(CRACK, "| ./level.elf"); print CRACK $try; close(CRACK); }
At first it takes one argument that contains the beginning of the string, we already verified. Afterwards the script just tries to append all human-readable characters to the string and passes it to the binary. The result is printed on the screen.
To get a proper output where the passphrase can be seen ad hoc this script should be used with “grep” and a regular expression that matches only the lines that indicate a success:
rup0rt@lambda:~/NcN2013$ ./crack.pl "" | grep -B 3 "^|.*\*\{1\}"
TRYING: (32)
| > Type to win, only what I want to read...
| > *
The expression matches only lines that first character is “|” and that contains the number of stars (correct characters) we are looking for (here: one). Using this technique we are able to brute force one character after the other.
rup0rt@lambda:~/NcN2013$ ./crack.pl " " | grep -B 3 "^|.*\*\{2\}" TRYING: S (83) | > Type to win, only what I want to read... | > ** rup0rt@lambda:~/NcN2013$ ./crack.pl " S" | grep -B 3 "^|.*\*\{3\}" TRYING: SU (85) | > Type to win, only what I want to read... | > *** [...] rup0rt@lambda:~/NcN2013$ ./crack.pl " SURPRISE" | grep -B 3 "^|.*\*\{10\}" TRYING: SURPRISE! (33) | > Type to win, only what I want to read... | > ********** rup0rt@lambda:~/NcN2013$ ./crack.pl " SURPRISE\!" | grep -B 3 "^|.*\*\{11\}"
After brute forcing 10 characters (” SURPRISE!”) no more results can be found. The reason seems to be that we already gained all characters we need to solve the challenge. So we execute the binary once more and enter the passphrase ” SURPRISE!”.
The key is 9e0d399e83e7c50c615361506a294eca22dc49bfddd90eb7a831e90e9e1bf2fb.