Narnia · OverTheWire

Narnia Level 6 → Level 7

Level 6

Username : narnia6
Password : neezocaeng
SSH : narnia.labs.overthewire.org:2226

Solution

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

Screenshot from 2017-08-12 16-27-23.png

8-12-2017 4-30-33 PM.png

As we can see above, the executable removes all the environment variables and arguments greater than 3 (argument 1 is the the executable call and arguments 2 and 3 are the two arguments passed to the executable). I was a little confused by the following line:

int (*fp)(char *)=(int(*)(char *))&puts

After refreshing my knowledge on pointers, I understood that the code is a function pointer initialized to point to puts(). Therefore whatever is passed to fp is simply printed on the console. As we know the strcpy is a vulnerable function to buffer overflow, let’s see if we can exploit it.

Screenshot from 2017-08-12 16-53-53.png

As we can see above, we can overflow the buffer and overwrite the return pointer. As we cannot utilize arguments and environment variable, we need to find a different way of gaining access to a shell. At this point, I decided to try and put a shellcode in the second argument in the hopes of being able to call that address by overflowing the argumnt 1 variable. However, since the length of the buffer is only 8 bytes, I ended up overflowing space allocated for argument 1 and replaced the return address with a word in the shellcode.

Screenshot from 2017-08-12 17-11-52.png

So now that we know that we cannot provide/store the shellcode in the executable, we need to think of a different way of exploiting it. Let’s look at the following code:

8-12-2017 5-34-43 PM.pngScreenshot from 2017-08-12 17-36-05.png

The code calls the system() function to execute ‘ls -l‘. Let’s now have a look at the internal workings of it in GDB.

Screenshot from 2017-08-12 16-23-17.png

As we can see above, right before the call to the system module is made, the command is pushed on the stack. Therefore, if we can call the system() function and pass ‘/bin/sh‘ to it, we might be able to access a shell.

Screenshot from 2017-08-12 19-27-48.png

As we can see above, we first find the address of the system() function and then pass our string ‘/bin/sh’ to it.

Screenshot from 2017-08-12 19-31-21.png

Level 7

Username : narnia7
Password : ahkiaziphu
SSH : narnia.labs.overthewire.org:2226
Narnia · OverTheWire

Narnia Level 5 → Level 6

Level 5

Username : narnia5
Password : faimahchiy
SSH : narnia.labs.overthewire.org:2226

Solution

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

Screenshot from 2017-08-08 00-03-06.png

8-8-2017 12-04-26 AM.png

As we can see above, the executable sets the value of a variable i to 1. There is a clause within the code that lets us access the shell if the value for i has been changed to 500. The exdcutable copies the value from the argument to the variable buffer by using the sprintf function with size bounds. Therefore, we cannot overflow it to change the value of i to 500. We need to find another way.

After spending a considerable amount of time working on this, I learned that some functions are vulnerable to Format String Vulnerability and sprintf function is one of them. I followed the following documents and I hope they help you too. Link 1, Link 2.

Let’s see what’s on the stack and learn more about this vulnerability.

Screenshot from 2017-08-08 00-19-59.png

As we can see above, the executable is vulnerable to Format String Vulnerability and we can see the stack contents. Let’s verify this in gdb to gain a better understanding.

Screenshot from 2017-08-08 00-27-32.png

As we can see, the executable is indeed printing the stack contents. Let’s follow the documents above and try to insert our value in the address of variable i.

Screenshot from 2017-08-08 00-35-39.png

As we can see, the executable prints our argument ‘ABCD’ on the fifth iteration of %08x. Instead of using the %08x format specifier the fifth time, I decided to use the %n format specifier and pass the address of variable i to it. By using the %n format specifier, we can see that the value at the address that we have passed changes to 40. A %n specifier is used as a reference to the number of bytes written so far. Let’s dissect why the application printed 40 in this case. As we can see, we have 4 bytes of the address in little-endian form, bytes of %x specifier printed times consuming 32 bytes and 1 byte of . symbol printed times totaling 4 bytes. 32+4+4=40 and that is the reason why the number was overwritten to 40 at variable i. Let’s now use the %u specifier to increase the width of the output thus tricking the %n specifier. The number we are writing — the count of characters written by the format function — is dependent on the format string. Since we control the format string, we can at least take influence on this counter, by writing more or less bytes. By using a dummy parameter ‘%nu’ we are able to control the counter written by ‘%n’, at least a bit. As we already have 40 bytes using our previous shellcode. Let’s increase it to change the value of i to 500.

Screenshot from 2017-08-08 11-18-47.png

As we can see above, after changing the width of the shellcode, the value of i is changed to 500.

Level 6

Username : narnia6
Password : neezocaeng
SSH : narnia.labs.overthewire.org:2226
Narnia · OverTheWire

Narnia Level 4 → Level 5

Level 4

Username : narnia4
Password : thaenohtai
SSH : narnia.labs.overthewire.org:2226

Solution

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

 

Screenshot from 2017-08-01 21-32-46.png

8-1-2017 9-33-27 PM.png

As we can see above, the executable doesn’t respond to any data provided as an argument and merely just exits after it’s done executing the commands. On looking at the code, we can see that the executable changes the data of environment variable to a Null character, thereby removing any shellcode that might be sitting in an environment variable.

The last few lines of the code are used to copy an argument provided to the executable into a buffer. My first impression was to use an environment variable similar to the previous two levels and somehow exploit the strlen function to think that my shellcode size is smaller than it is and preserve the shellcode in the environment variable.

Screenshot from 2017-08-01 21-45-31.png

As we can see above, the executable removes the content of an environment variable. After messing with it for a few times, I decided to take a different approach and look into the buffer variable. The executable simply copies the content of the argument to the buffer variable without checking for limit bounds. Therefore, if we can exceed the bounds, we can potentially create a buffer overflow and re-write the return pointer to the address of our shellcode which would be provided in the argument to the executable. Let’s try to find out how many bytes are needed to overflow the buffer.

Screenshot from 2017-08-01 21-51-20.png

As we know the size of the buffer variable is 256 characters, I decided to start with 260 characters and proceed upwards until I find my first Segmentation Fault. As we can see above, after inputting 272 characters, the executable returned an ‘Illegal Instruction’. From what I’ve seen in my past experiences, when the base pointer of the previous function is overwritten and not the return pointer, the executable responds with this error message. Therefore, 4 more bytes over this will re-write the return pointer. At this point I decided to run the program in gdb and figure out the address of my buffer. We can see that the executable uses strcpy to copy data from the argument to the buffer. Therefore, I set a breakpoint after strcpy function to see where the data was copied.

Screenshot from 2017-08-01 21-58-34.png

As the executable loads the effective address of ‘$esp+0x1c’, I decided to jump to that location and see if that’s the address of the buffer variable. The argument value that I provided was there in the buffer. Therefore, my next step was to create a slide of NOP’s and put my shellcode in between.

Screenshot from 2017-08-01 22-23-30.png

As we can see above, by using the shellcode used in the previous levels, we were able to re-write the return pointer to our shellcode address.

Level 5

Username : narnia5
Password : faimahchiy
SSH : narnia.labs.overthewire.org:2226
Narnia · OverTheWire

Narnia Level 3 → Level 4

Level 3

Username : narnia3
Password : nairiepecu
SSH : narnia.labs.overthewire.org:2226

Solution

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

Screenshot from 2017-07-31 19-07-20.png

7-31-2017 7-08-58 PM.png

As we can see above, the executable reads a file that user provides and copies its content to ‘/tmp/null‘. ‘/tmp/null‘ is a special file that discards all data written to it but reports that the write operation succeeded. For more information on it, read this wikipedia page.

On a first pass at the C code, we can see that it utilizes the vulnerable strcpy function with no check on size limits. The allocation for an input file name is 32 bytes and the output file is 16 bytes. Let’s look at the code in a debugger.

Screenshot from 2017-07-31 19-17-01.png

We can see above that the executable copies the string name stored at 0x58(%esp) first and then the string name stored at 0x38(%esp). Both these locations probably store the file names to be opened. Therefore, we can conclude that if we overflow the buffer for input file name, we can modify the name for output file as well and possibly change it to something other than the null device.

Let’s confirm this theory by providing a filename more than 32 characters and breaking the flow in gdb before the files are opened.

Screenshot from 2017-07-31 19-26-27.png

As we can see, there are two breakpoints set and a long filename passed to the executable. At the first breakpoint which is right before the output file is opened, the value is set to “7890” and we can see in the next few statements that the file tried to be opened is “7890” which is 32 characters after our input file name. Therefore, we are successfully able to change the output file name. Let’s create a file “7890” and see how the input file looks like at the second breakpoint.

Screenshot from 2017-07-31 19-28-13.png

As we can see, the input filename is the one we provided to the executable. Therefore, now we control the input file and the output file. Let’s provide the executable an input file which contains or references the password and an output file which we control.

To solve this, I created a folder within /tmp called Narnia0003 and a folder within it called SecurityTimes003. The total length of the following string is 32 bytes.

/tmp/Narnia0003/SecurityTimes003

Therefore, anything that follows the above path will overwrite the output file. To solve that, I created an output file within /tmp named output. I also created an input file named output within a folder named tmp  which nests under /tmp/Narnia0003/SecurityTimes003. If we symbolically link this file to the password file, we can use it as the input file and the output file will be re-written to /tmp/output which is a file we can view.Screenshot from 2017-07-31 19-38-18.png

As we can see above, the executable updates the output file to our file and prints the password for the next level in it.

 

Level 4

Username : narnia4
Password : thaenohtai
SSH : narnia.labs.overthewire.org:2226
Narnia · OverTheWire

Narnia Level 2 → Level 3

Level 2

Username : narnia2
Password : nairiepecu
SSH : narnia.labs.overthewire.org:2226

Solution

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

Screenshot from 2017-07-27 12-54-49.png

7-27-2017 12-53-45 PM.png

As we can see, the executable copies the argument into a buffer and then prints it. The buffer size allocated is 128 characters. Therefore, if we can overflow the buffer by inserting more bytes than the executable expects, we can re-write the instruction pointer (EIP) to execute our shellcode. This level is very similar to the last level, however, this time around, the executable does not run our shellcode. We need to place our shellcode at a location whose address we are aware of and the executable can jump to it. In this scenario, I can think of two easy ways to solve this:

  1. Put the shellcode in the buffer and then jump to it after finding it’s address.
  2. Put the shellcode in an environment variable and jump to that address.

Since this level is very similar to the previous level, I decided to use environment variable to execute the shellcode. In the previous level, the executable executed our shellcode within the variable, however, this time around, we will need to replace the return pointer to jump to our shellcode address.

Let’s first determine after how many bytes does the executable overflows the return pointer.

Screenshot from 2017-07-28 15-43-35.png

As we can see above, the return pointer is overwritten after 140 characters. Therefore, we need to input our shellcode address after 140 characters.

Screenshot from 2017-07-28 15-40-09.png

Using the above programs, we will now create a simple python script to overflow the return pointer with the address returned by findeggaddr executable.

Screenshot from 2017-07-28 15-51-12.png

As we can see above, despite having an address for the shellcode, the executable throws a Segmentation Fault error with no core dump. At this point, to evaluate the core, I decided to make a copy of narnia2 executable in my temp directory and understand what’s happening behind the scene.

Screenshot from 2017-07-28 15-55-06.png

As we can see, the executable does return to our address, however, it still segment faults. Let’s see if our environment address is correct or not.

Screenshot from 2017-07-28 15-57-50.png

As we can see above, our address for EGG was incorrect and we can find the correct address by reading the environment variables inside gdb. After getting the correct value for shellcode address, we can execute narnia2 to get the password for the next level.

Level 3

Username : narnia3
Password : vaequeezee
SSH : narnia.labs.overthewire.org:2226
Narnia · OverTheWire

Narnia Level 1 → Level 2

Level 1

Username : narnia1
Password : efeidiedae
SSH : narnia.labs.overthewire.org:2226

Solution

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

Screenshot from 2017-07-24 12-38-03.png

7-24-2017 12-43-10 PM.png

As we can see, the executable checks for the existence of an environment variable named ‘EGG’. To read more on environment variables, click here. Therefore, we need to create our shellcode and store it in the environment variable. The executable would then execute our shellcode for us. This would be a good point to read on Buffer Overflow if you’re unfamiliar with that. This link provides good information about it. Since we would be executing our shellcode from the environment variable, this link provides a really nice script to store our shellcode. Let’s now create our shellcode and store that in the ‘EGG’ environment variable.

Screenshot from 2017-07-25 12-49-48.png

As we can see above, we now have the shellcode. Let’s store this in the variable now.

Screenshot from 2017-07-25 12-57-17.png

Now that our shellcode is loaded, let’s execute ‘narnia1’

Screenshot from 2017-07-25 13-11-07.png

Level 2

Username : narnia2
Password : nairiepecu
SSH : narnia.labs.overthewire.org:2226
Narnia · OverTheWire

Narnia Level 0 → Level 1

Level 0

Username : narnia0
Password : narnia0
SSH : narnia.labs.overthewire.org:2226

Solution

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

Screenshot from 2017-07-23 14-21-21.png

7-23-2017 2-22-41 PM.png

As we can see, the executable declares a buffer for 20 characters. However, while scanning for the buffer, the executable allows up to 24 characters to be scanned in the buffer. Such a condition can result in buffer overflow. To read more on it, check this link. We can overflow the buffer to replace the value of variable ‘val’. We can replace the value to ‘0xdeadbeef’. I wrote the following script to see if we can overflow the buffer.

python -c 'print "A"*20+"\x10\x10\x10\x10"' | ./narnia0

Screenshot from 2017-07-23 16-14-32.png

As we can see, after passing 20 ‘A’ characters, the input overflows the buffer and replaces the value of ‘val’ to ‘0x10101010’ which are the last 4 input characters. Therefore, as we now know that we can overflow the buffer easily, let’s replace the value to ‘0xdeadbeef’.

Screenshot from 2017-07-23 16-15-02.png

As we can see above, the executable overflows the buffer, however, the shell closes before we have the opportunity to execute any commands. Therefore, we need to find a way to make the shell persist and not exit. To do that, we need to pass a command to the shell that makes it persist until we send the input. Commands like ‘cat’ can help us achieve that.

Screenshot from 2017-07-23 17-17-54.png

As we can see above, we can read the password for the next level now.

Level 1

Username : narnia1
Password : efeidiedae
SSH : narnia.labs.overthewire.org:2226