Getting Started with Pwnable.kr

This post is the first in a series about pwnable.kr; an open online CTF open to anyone who’d like to try their hand at the challenges it provides. As with many CTFs, if this is your first or you’re new to the concepts that it relies on, the challenges can seem quite daunting. Through this series we’re going to try to cover not only the solutions, but why they work, and where you can find more information regarding each.

VPN Recommended: You’re logging into a remote SSH Server, and therefore your IP Address information may become viewable to other users. Use a VPN to mask your true IP.

 

fd pwnable.krLets get on to the first challenge.

FD – The First Challenge.

Logging into the SSH Server presents us simply with a directory for the fd user. Run a quick ls -l to pull the files in our directory to see what we’re working with.

Ok, so we have a flag file, fd (a binary executable) and fd.c, the source code used to build the program. Flag is marked unreadable by the user, so we’ll need to manipulate fd to get our flag (and our first point).

View the contents of fd.c (using either your favorite editor, like vim or nano; or simply cat). Gives us the following code:

Ok, looks like our executable program requires some inputs to work correctly, namely: we need to feed the variable ‘buf’ a value of “LETMEWIN” to trigger the system(“/bin/cat flag”) call and print our flag. However upon reading more closely, ‘buf’ is not assigned through command line arguments. Trying the command <pre>./fd</pre> gives us the expected error of “pass a number”. But what number to pass?

The answer lies in the basic I/O options inherent in most *nix based operating systems. You can read more on stdin, stdout and stderr on Wikipedia or even read about this exercises namesake File Descriptors. In short, these are pre-built interfaces for programs to get input or output text to their host operating systems. For our purposes we want to accept input from the user, so we need to use a fd of 0, which stands for stdin.

The line where we’re getting user input is  len = read(fd, buf, 32); this is telling our program to use read to accept some form of input. The function accepts 3 arguments, they are handle, buffer, length. The important one for this problem is handle. We need handle to equal zero so that the program reads our input from stdin.

We can see fd is calculated by  int fd = atoi( argv[1] ) - 0x1234;  which takes our command line input, subtracts the hexadecimal number of 0x1234, and assigns it to fd. So all we need to do is convert 0x1234 to decimal, and use that as our input for the program. A quick conversion gives us the decimal value of 4660.

Run fd with that value, punch in our key phrase of “LETMEWIN”.

And theres our flag! First down, many to go.

Next up, we’ll be looking at Hash Collisions; so keep tuned. If you’re having any trouble with the fd problem, you can join into IRC at any time from the pwnable.kr ssh window by typing irssi; or join us on the Shadowless.net channel on freenode; or drop us a comment below!