in the name of zero

February 20, 2006

execve with arguments

Filed under: hermetic studies

so far, i’ve only been doing simple program loading using sys_execve in shellcodes. simple in the sense that no arguments are being passed to loaded programs. unfortunately, running a program without any argument produces rather boring outputs. today, i added a bit of twist to things. i tried to implement a shellcode that chroots into a particular directory.

first, an introduction.

chroot or “change root” for that matter makes it possible for a user to run a command or interactive shell within a special ‘user defined’ directory.

of course, a little bit of preparation is required before running chroot. one needs to imitate his/her root directory. here’s how mine went.

first, i made a directory that will act as my fake root.

steph@heaven ~ $ mkdir myroot ; cd myroot

once i’m in my fake root, i’ll be using /bin/bash, /bin/ls and /bin/pwd so i also need to create a bin directory inside my fake root where bash, ls and pwd will reside.

steph@heaven ~/myroot $ mkdir bin

then i copied the bash, ls and pwd binaries into it from my ‘real’ root.

steph@heaven ~/myroot $ cp /bin/bash bin/
steph@heaven ~/myroot $ cp /bin/ls bin/
steph@heaven ~/myroot $ cp /bin/pwd bin/

things are not done yet! i still had to resolve their shared library dependencies for them to work! i first resolved /bin/bash’s dependencies.

steph@heaven ~/myroot $ ldd /bin/bash
        linux-gate.so.1 =>  (0xffffe000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7f19000)
        libc.so.6 => /lib/libc.so.6 (0xb7e01000)
        /lib/ld-linux.so.2 (0xb7f28000)

it uses some files inside /lib! so inside my fake root, i also create a lib directory and copied the shared objects there.

steph@heaven ~/myroot $ mkdir lib
steph@heaven ~/myroot $ cp /lib/libdl.so.2 lib/
steph@heaven ~/myroot $ cp /lib/libc.so.6 lib/
steph@heaven ~/myroot $ cp /lib/ld-linux.so.2 lib/

i did the same for ls and pwd. printing their shared dependencies using ldd, then copying them to their respective directories inside my fake root. after copying, i verified if everything was in place.

steph@heaven ~/myroot $ ls -l *
bin:
total 761
-rwxr-xr-x  1 steph users 680316 Feb 19 15:33 bash
-rwxr-xr-x  1 steph users  75268 Feb 19 15:33 ls
-rwxr-xr-x  1 steph users  15716 Feb 19 15:26 pwd
	
lib:
total 1301
-rwxr-xr-x  1 steph users   83620 Feb 19 15:36 ld-linux.so.2
-rwxr-xr-x  1 steph users 1228960 Feb 19 15:36 libc.so.6
-rwxr-xr-x  1 steph users   10892 Feb 19 15:36 libdl.so.2
groovy! my fake root looks like a real simple root now! time to test it.

steph@heaven ~ $ chroot /home/steph/myroot /bin/bash
chroot: cannot change root directory to /home/steph/myroot: Operation not permitted
oopsie! i guess i better run chroot as “root”.

heaven steph # chroot /home/steph/myroot /bin/bash
bash-3.00#

it worked! let’s try running some commands inside the fake root shall we?

heaven steph # chroot /home/steph/myroot /bin/bash
bash-3.00# ls
bin  lib
bash-3.00# pwd
/
bash-3.00# cat
bash: cat: command not found
i tried running three commands inside my fake root. first was ls. and it showed the contents of my chrooted directory. next was pwd and it showed my present working directory, that happens to be “/” of my fake root. and lastly, cat. but it didn’t work. that is because i don’t have cat inside my fake root. i only copied three files and their corresponding dependencies. a good chroot directory must have all the important files or binaries for it to be productive. also, it must not contain useless files that won’t be used. in my case, it was the cat command.

lastly, i exited my chroot environment and copied the fake root folder (myroot) to where the real fun will happen. inside my git repository!

steph@heaven ~ $ cp -r myroot ~/git/null/asm/shellcoding/

it was too bad that i had to run chroot as “root”. quite creepy.

next page: the shellcode

based on the activity above, i’m supposed to run chroot as follows /usr/bin/chroot ./myroot /bin/bash. that implies that my shellcode expects to find a directory “myroot” from where i’d be running it. that’s two arguments passed to chroot! well, three if you count the path to the program also. as usual, i first tried everything on a normal assembly listing. based on which, i came up with the shellcode below.

        global _start
 section .text
 _start:
         jmp short .setup
	
 .shellcode:
         pop ebx                 ; ebx holds string addr
         xor eax, eax            ; eax = null
	
         mov [ebx+15], al        ; segregation
         mov [ebx+24], al        ; ditto
	
         lea esp, [esp-16]       ; room on stack
         and esp, -16
	
         mov [esp], ebx          ; '/usr/bin/chroot' addr in first dword
         lea ecx, [ebx+16]
         mov [esp+4], ecx        ; './myroot' addr in second dword
         lea ecx, [ebx+25]
         mov [esp+8], ecx        ; '/bin/bash' addr in third dword
         xor ecx, ecx            ; see also xor eax, eax above
         mov [esp+12], ecx       ; null pad in fourth dword
	
         mov al, 11              ; sys_execve
         lea ecx, [esp]          ; char *const argv[]
         xor edx, edx
         int 0x80                ; pray it works!
	
 .setup:
         call .shellcode
         cmd db '/usr/bin/chroot ./myroot /bin/bash'
assembled, this would generate the following opcodes.

Disassembly of section .text:
	
080480a0 <.text>:
 80480a0:       eb 33                   jmp    0x80480d5
 80480a2:       5b                      pop    %ebx
 80480a3:       31 c0                   xor    %eax,%eax
 80480a5:       88 43 0f                mov    %al,0xf(%ebx)
 80480a8:       88 43 18                mov    %al,0x18(%ebx)
 80480ab:       8d 64 24 f0             lea    0xfffffff0(%esp),%esp
 80480af:       81 e4 f0 ff ff ff       and    $0xfffffff0,%esp
 80480b5:       89 1c 24                mov    %ebx,(%esp)
 80480b8:       8d 4b 10                lea    0x10(%ebx),%ecx
 80480bb:       89 4c 24 04             mov    %ecx,0x4(%esp)
 80480bf:       8d 4b 19                lea    0x19(%ebx),%ecx
 80480c2:       89 4c 24 08             mov    %ecx,0x8(%esp)
 80480c6:       31 c9                   xor    %ecx,%ecx
 80480c8:       89 4c 24 0c             mov    %ecx,0xc(%esp)
 80480cc:       b0 0b                   mov    $0xb,%al
 80480ce:       8d 0c 24                lea    (%esp),%ecx
 80480d1:       31 d2                   xor    %edx,%edx
 80480d3:       cd 80                   int    $0x80
 80480d5:       e8 c8 ff ff ff          call   0x80480a2
 80480da:       2f                      das
 80480db:       75 73                   jne    0x8048150
 80480dd:       72 2f                   jb     0x804810e
 80480df:       62 69 6e                bound  %ebp,0x6e(%ecx)
 80480e2:       2f                      das
 80480e3:       63 68 72                arpl   %bp,0x72(%eax)
 80480e6:       6f                      outsl  %ds:(%esi),(%dx)
 80480e7:       6f                      outsl  %ds:(%esi),(%dx)
 80480e8:       74 20                   je     0x804810a
 80480ea:       2e                      cs
 80480eb:       2f                      das
 80480ec:       6d                      insl   (%dx),%es:(%edi)
 80480ed:       79 72                   jns    0x8048161
 80480ef:       6f                      outsl  %ds:(%esi),(%dx)
 80480f0:       6f                      outsl  %ds:(%esi),(%dx)
 80480f1:       74 20                   je     0x8048113
 80480f3:       2f                      das
 80480f4:       62 69 6e                bound  %ebp,0x6e(%ecx)
 80480f7:       2f                      das
 80480f8:       62 61 73                bound  %esp,0x73(%ecx)
 80480fb:       68                      .byte 0x68
of course i still had to put those inside a string and call it from c.

char root[] = "\xeb\x33\x5b\x31\xc0\x88\x43\x0f\x88\x43\x18\x8d\x64\x24\xf0\x81\"\
               \"\xe4\xf0\xff\xff\xff\x89\x1c\x24\x8d\x4b\x10\x89\x4c\x24\x04\x8d\"\
               \"\x4b\x19\x89\x4c\x24\x08\x31\xc9\x89\x4c\x24\x0c\xb0\x0b\x8d\x0c\"\
               \"\x24\x31\xd2\xcd\x80\xe8\xc8\xff\xff\xff\x2f\x75\x73\x72\x2f\x62\"\
               \"\x69\x6e\x2f\x63\x68\x72\x6f\x6f\x74\x20\x2e\x2f\x6d\x79\x72\x6f\"\
               \"\x6f\x74\x20\x2f\x62\x69\x6e\x2f\x62\x61\x73\x68";
	
 typedef int (*fp)();
	
 void exec(int (*fp)())
 {
         fp();
 }
	
 int main(int argc, char **argv)
 {
         exec((fp)root);
         return 0;
 }
and then i compiled and executed the c program that contains my chroot shellcode.

steph@heaven ~/git/null/asm/shellcoding $ su
Password:
heaven shellcoding # ./print_str
bash-3.00# ls
bin  lib

well it worked. i succesfully chrooted to my fake root directory. i had lots of fun doing this and i hope i’ve entertained whoever is reading this at this moment (no one i guess). i’ll go girl hunting at friendster now. bye bye.

Comments »

The URI to TrackBack this entry is: http://gnurbs.blogsome.com/2006/02/20/execve-with-arguments/trackback/

No comments yet.

RSS feed for comments on this post.

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>


Get free blog up and running in minutes with Blogsome | Theme designs available here