Narnia Level 0
28 Sep 2015 • LeanderThis is a solution guide to the Narnia0 Level at overthewire. This write-up was created on 19 November 2014.
Challenge Description: Narnia0 is the beginning challenge for pwnable style challenges on overthewire. It requires the attacker to utilize a buffer overflow in order to overwrite a variable named val with the hexidecimal value 0xdeadbeef. When the attack is successful the vulnerable program will execute a system command which produces a shell. This challenge requires the attacker to send hexidecimal values after determining the buffer overflow offset.
First connect to the lab
- ssh narnia0@narnia.labs.overthewire.org
- Enter the following as the password narnia0
Change directories to the narnia games folder cd /narnia
. First let’s examine how we get the password for the next level less /README.txt
. This machine holds several wargames. For a generic wargame named “somegame”, the usernames are: mygame0, mygame1, … and most levels are stored in /mygame/. Passwords for each level are stored in /etc/mygame_pass/
So let’s try reading the password without any additional work, cat /etc/narnia_pass/narnia1
Well that didn’t work, so lets check out the challenge next. Notice all the different files and find the level 0 binary.
I start by checking what the file does
Well that’s interesting that it did something weird with %p. Now let’s check the source code, type out cat narnia0.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <stdlib.h>
int main(){
long val=0x41414141;
// notice the buffer here is 20, which means there may be a potential for a buffer overflow
char buf[20];
printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
printf("Here is your chance: ");
scanf("%24s",&buf);
//notice the buffer read in from the command prompt above is a 24 byte string
//this means that we have a 4 byte overflow
printf("buf: %s\n",buf); //here it prints the 20 bytes from char buf
printf("val: 0x%08x\n",val); //the 4 bytes that overflow fall into val
//because it was initialized on the stack below it
if(val==0xdeadbeef) //a successful overflow input will give me a shell!
system("/bin/sh"); //system passes a command to the shell and in
//this case attempts to open a shell
else {
printf("WAY OFF!!!!\n");
exit(1);
}
return 0;
}
From inspecting the code we can see that the stack looks something like this:
Alright now that I know this let’s try some crafted input.
Well that’s great, we’ve just confirmed that we can affect what goes into long val. It’s confirmed that i can overwrite the buffer. Apaprently, I was correct in how the stack looked and inside it would look similar to this (except in hexadecimal representation).
Note that 0x41 = A and 0x42 = B, char buff is ( 20 bytes ), and long val is ( 4 bytes ). Now let’s try it with deadbeef in there.
Well that didn’t work, because scanf is accepting string characters. So now we need a way to get the proper “characters” in so that it will display 0xdeadbeef. Remember that you also have to craft the input to be little endian (I think of this as the input has to be spelled backwards).
Well that’s weird I didn’t get a shell, but the WAY OFF!!!! didn’t show. At this point I realized that the /bin/sh needed an input to follow the system command. So then I added more input onto the end.
Still no solution. Now I want to create a situation where the program does something unintentional.
So I discovered I had the stack improperly setup because a long is actually 4096 bytes in size. This was demonstrated by the fact /bin/sh received the input that overflowed from the crafted string that I sent. Well that was useful, now lets whittle it down so that the /bin/sh command takes the correct input. All I should have to do now is remove the extra bytes.
BINGO! We have a solution. The password file for narnia1 is efeidiedae
.