Narnia · Pwnable.kr

Pwnable.kr Toddler’s Bottle writeup

fd

Username : fd
Password : guest
SSH : pwnable.kr:2222

Solution

To solve this level, we first ssh into the pwnable server using the credentials provided above. Let’s have a look at the executable for this level and its source code.

Screenshot from 2017-09-09 13-34-53.png

9-9-2017 1-36-11 PM.png

As we can see above, the executable expects a number to be passed to it. It then uses the number passed to calculate a file descriptor, fd which is then used to open a file. If the content of the file pointed by the fd pointer contains ‘LETMEWIN’ then the executable prints our flag.

To start off, let’s have a look at the Wikipedia page of file descriptor and understand what it is and why it’s needed. As we can see, the main purpose of the file descriptor is to provide us a channel to perform operations on a file. Each file descriptor performs a specific task (read/write) on a file.

As the executable compares the file content of the file pointed by fd with ‘LETMEWIN’, if we can create a file containing ‘LETMEWIN’ and know its file descriptor number, we can pass it to the executable to capture our flag. We can also see in the Wikipedia page that the value 0 for a file descriptor is a pipe to standard input. therefore, if we can change fd’s value to 0, we will be able to enter ‘LETMEWIN’ using standard input and capture the flag. To set the value of fd to 0, we need to pass 4660 (0x1234) to the executable as it is subtracted by that amount in the executable.

Screenshot from 2017-09-09 13-50-34.png

Flag : mommy! I think I know what a file descriptor is!!

collision

Username :col
Password : guest
SSH : pwnable.kr:2222

Solution

To solve this level, we first ssh into the pwnable server using the credentials provided above. Let’s have a look at the executable for this level and its source code.

Screenshot from 2017-09-09 14-04-42.png

9-9-2017 2-05-39 PM.png

As we can see above, the executable expects a 20 character password and creates a hash using it. This hash is then compared against a stored hash, hashcode. If the hashes match, the executable prints the flag. Let’s understand how the executable is creating the hash by creating our own c program and adding print statements at important sections.

Screenshot from 2017-09-09 15-23-24.png

As we can see above, the executable converts our characters to an integer value and then uses it to compare against the stored value “0x21DD09EC”. Now that we understand how the hash is computed, we need to make the sum equal to the stored value. To do this, I simply divided the desired value by 5.

Screenshot from 2017-09-09 15-30-19.png

As we can see above, passing “0x06c5cec9” four times and “0x06c5cec8”, creates our desired hash value. Let’s now pass this value to the executable to capture the flag.

Screenshot from 2017-09-09 15-33-00.png

Flag : daddy! I just managed to create a hash collision :)

bof

Download C File : http://pwnable.kr/bin/bof.c
Download Executable: http://pwnable.kr/bin/bof
NC : pwnable.kr:9000

Solution

To solve this level, we first ssh into the pwnable server using the credentials provided above. Let’s have a look at the executable for this level and its source code.

Screenshot from 2017-09-10 22-04-00.png

9-10-2017 10-04-24 PM.png

As we can see above, the executable asks the user to input something which is put in the overflow variable. The main program of the function send the value 0xdeadbeef as a key to the function func. In the func function, the key is checked against the value 0xcafebabe. If the key is the same as this value, it opens a shell for us.

Since this problem seems like a simple buffer overflow problem and it’s something that we have dealt with before, let’s fire up gdb and analyse the functions.

Screenshot from 2017-09-10 22-11-28.png

As we can see above, the application loads effective address of $ebp-0x2c into $eax before calling the gets function (func+36). The value 0xcafebabe is compared against the value stored at $ebp+0x8, therefore, that is the location of the variable key. Let’s analyse what’s stored at these points to determine how we can best exploit the executable.

Screenshot from 2017-09-10 22-26-37.png

As we can see, the difference between the address that we control (overflow) and the one that we need to overwrite (key) is 52 bytes. Therefore, if we pass 52 bytes of random string and “0xcafebabe” with it, we will be overwrite the key variable.

Screenshot from 2017-09-10 22-43-27.png

As we can see, the executable gives us the flag after we’ve successfully overflown the buffer.

Flag : daddy, I just pwned a buFFer :)

flag

Download Executable: http://pwnable.kr/bin/flag

Solution

To solve this level, we first download  the executable using the information provided above. Let’s have a look at the executable for this level.

Screenshot from 2017-09-11 11-40-34 - Copy.png

As we can see above, the executable prints a statement and exits. Let’s inspect the file in gdb.

Screenshot from 2017-09-11 11-40-34.png

Hmm, gdb could not print any information about the executable. Let’s check for file information.

Screenshot from 2017-09-11 11-40-34 - Copy (2).png

As we can see above, I compared the file information for flag and bof file. File flag is stripped, however, the bof file is not. What this means is that the developers for the executable flag stripped the data points that is required by a gdb to assist us in debugging and hence gdb is unable to show any information. At this point, I decided to run the strings command on the file to see if I can find some more information.

Screenshot from 2017-09-11 13-12-34.png

As we can see above, the output returned the string “UPX!” in the head and the tail of the output and I decided to google what it meant. I came across UPX’s website and it’s wikipedia entry says “UPX (Ultimate Packer for Executables) is a free and open source executable packer supporting a number of file formats from different operating systems.”. Now that we understand that the file flag has been packed using this program. Let’s unpack this file and evaluate it in gdb.

Screenshot from 2017-09-11 11-25-50.png

Screenshot from 2017-09-11 13-18-35 - Copy.png

Now that we can use gdb to inspect the file, line number 32 in particular looks interesting as it seems to be a call to the flag function. Let’s see what the output of the flag function is which is put into the register rdx.

Screenshot from 2017-09-11 13-18-35.png

As we can see above, the result of the call to the flag function is our flag for the problem.

Flag : UPX...? sounds like a delivery service :)

random

Username : random 
Password : guest 
SSH : pwnable.kr:2222

Solution

To solve this level, we first ssh into the pwnable server using the credentials provided above. Let’s have a look at the executable for this level and its source code.

Screenshot from 2017-09-17 10-14-51.png

9-17-2017 10-14-31 AM.png

As we can see above, the executable creates a random integer by calling rand()  function. It then XOR’s the random number with the user’s input and if the value matches 0xdeadbeef, the executable prints our flag. Let’s compile this program and print the value of random number.

9-17-2017 10-08-47 AM.png

As we can see above, the value generated by the rand() function is always constant, 1804289383. The rand() function is used to print a pseudo-random integral number. This number will be in the range 0 to RAND_MAX. The algorithm of rand() uses a seed to generate the series of numbers, this is why srand must be used to initialize the seed to some distinctive value. Since in this case, the executable does not create a seed for rand() function, rand() returns the same value every time.

Since we know the vulnerability now, let’s find the the proper value for key. Let’s XOR 0xdeadbeef with 0x6B8B4567 (1804289383) and use the result as our input. This works because of XOR’s transitivity property. Hence, our input should be 3039230856.

Screenshot from 2017-09-17 10-42-40.png

Flag : Mommy, I thought libc random is unpredictable...

mistake

Username : mistake
Password : guest 
SSH : pwnable.kr:2222

Solution

To solve this level, we first ssh into the pwnable server using the credentials provided above. Let’s have a look at the executable for this level and its source code.

Screenshot from 2017-09-25 10-15-59.png

9-25-2017 10-17-24 AM.png

As we can see above, the executable reads a password from a file named ‘password’. It then gets a password from the user and XOR’s it with 1. It then compares this XORed password with the password retrieved from the password file and if they’re the same, it prints the flag. There’s also a sleep function right after it retrieves the password from the file. The hint for this level is : operator priority.

On running the executable for the first time, the biggest element of surprise was that the executable does not proceed to print “input password” after the sleep command. I had to press enter for the executable to print “input password”. This is something I found interesting and I wasn’t sure why this was happening.  Now let’s have a look at operator priority as that’s a hint given to us.

9-27-2017 11-12-14 AM.png

As we can see above“<” has preference over “=”. Now let’s have a look at the fd operation in the source code.

if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0)
{
    printf("can't open password %d\n", fd);
    return 0;
}

As we are now aware of operator precedence, we know that open(“/home/mistake/password”,O_RDONLY,0400) < 0 is executed before fd=open(“/home/mistake/password”,O_RDONLY,0400). Let’s understand what the developer intended and what the mistake  is. The developer wanted to check whether the program is able to open the password file. The open function returns the file descriptor for the new file. The file descriptor returned is always the smallest integer greater than zero that is still available. If a negative value is returned, then there was an error opening the file. Therefore, the developer wanted to check if fd < 0, but what the developer did not understand is operator precedence.

Since the open function call returns the file descriptor (hoping the file is available), open(“/home/mistake/password”,O_RDONLY,0400) < 0 returns 0. Therefore setting the value of fd to 0. By looking at the Wikipedia entry for File Descriptor=0, things start to get a lot clearer. The reason why we had to press enter to move on to next statement is because fd=0 is STDIN. Therefore, the executable is waiting for input from (Drum Roll!!) the user.

This problem is fairly easy now, we input the first value and the second value we enter is XORed and evaluated against our first value.

Screenshot from 2017-09-25 10-03-42.png

As we can see above, the executable prints our flag based on our input matching with XORed password.

Flag : Mommy, the operator priority always confuses me :(

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s