My first Handmade shell code!!

What is shell code?? (Wiki Definition)
In computer security, a shellcode is a small piece of code used as the payload in the exploitation of software vulnerability.
Shellcode is commonly written in machine code, but any piece of code that performs a similar task can be called shellcode.
It is called "shellcode" because it typically starts a command shell from which the attacker can control the compromised machine.
An exploit will commonly inject a shellcode into the target process before or at the same time as it exploits a vulnerability to gain control over the program counter. The program counter is adjusted to point to the shellcode, after which it gets executed and performs its task. Injecting the shellcode is often done by storing the shellcode in data sent over the network to the vulnerable process, by supplying it in a file that is read by the vulnerable process or through the command line or environment in the case of local exploits.

Shell code can be of two types.

Local Shell code and Remote Shell code.
Here i will write a simple Local shell code which will just generate a "MessageBOX"
Tools i generally use for shell coding are....
1)Nasm (Assembler )
2)Objdump(You can get this with Dev C++)
3)Dev C++
4)Ollydebug or you can use any debugger.
5)Arwin The C code freely available ,Get that and compile with any c compiler.


I did this entire thing on windows platform but,if you are a linux user you can do the same thing on any distribution of Linux.
But the main difference between Linux and windows shell code is
Linux, unlike windows, provides a direct way to interface with the kernel through the int 0x80 interface.
Windows on the other hand, does not have a direct kernel interface. The system must be interfaced by loading .the address of the function that needs to be executed from a DLL (Dynamic Link Library).The key difference between the two is the fact that the address of the functions found in windows will vary from OS version to OS version while the int 0x80 syscall numbers will remain constant.
First thing you have do while writing a working shell code for windows platform is, find the addresses of your needed DLL functions.

So to do that the tool i generally use is arwin.You can do the same thing by using any debugger. I will not explain that but using arwin is much simpler and easier.
The library functions i will be using for this simple shell code are "LoadLibraryA",'GetProcAddress", "MessageBoxA" and "ExitProcess"
Let's fire up arwin and find the addresses we need to use.
You just have to do the following things to get addresses of our required functions...

D:\exploitkit\arwin>arwin kernel32.dll GetProcAddress
arwin - win32 address resolution program - by steve hanna - v.01
GetProcAddress is located at 0x77e7b332 in kernel32.dll

D:\exploitkit\arwin>arwin kernel32.dll LoadLibraryA
arwin - win32 address resolution program - by steve hanna - v.01
LoadLibraryA is located at 0x77e7d961 in kernel32.dll


D:\exploitkit\arwin>arwin kernel32.dll ExitProcess
arwin - win32 address resolution program - by steve hanna - v.01
ExitProcess is located at 0x77e798fd in kernel32.dll



Now we have the required addresses...


After getting that you have to write down the code into assembly....so here is the code.....

; Assembly code starts here.....
[SECTION .text]

global _start


_start:

xor eax,eax
xor ebx,ebx   ;zero out the registers
xor ecx,ecx
xor edx,edx

jmp short GetLibrary
LibraryReturn:
pop ecx   
mov [ecx + 10], dl 
mov ebx, 0x77e7d961  ;LoadLibraryA(libraryname);
push ecx   ;beginning of user32.dll
call ebx  

jmp short FunctionName
FunctionReturn:

pop ecx  
xor edx,edx
mov [ecx + 11],dl 
push ecx
push eax
mov ebx, 0x77e7b332  ;GetProcAddress(hmodule,functionname);
call ebx   

jmp short Message
MessageReturn:
pop ecx    ;get the message string
xor edx,edx   
mov [ecx+3],dl  

xor edx,edx

push edx   ;MB_OK
push ecx   ;title
push ecx   ;message
push edx   ;NULL window handle

call eax   ;MessageBoxA(windowhandle,msg,title,type); Addre

ender:
xor edx,edx
push eax   
mov eax, 0x77e798fd   ;Address of Exitprocess;
call eax   ;exit cleanly so we don't crash the parent program



GetLibrary:
call LibraryReturn
db 'user32.dllN'
FunctionName
call FunctionReturn
db 'MessageBoxAN'
Message
call MessageReturn
db 'You are Hacked by Raza'

After that save the code as Shell.asm


Now its time to get the raw binary of the code we have just written.


To do that you have to use nasm assembler and objdump.

D:\exploitkit\nasm>nasm -f elf shell.asm
D:\exploitkit\>ld.exe -o shell shell.o
D:\exploitkit>objdump -d shell

The out put will be like this…
shell:     file format elf32-i386

Disassembly of section .text:

08048080 <_start>:
8048080:       31 c0                   xor    %eax,%eax
8048082:       31 db                   xor    %ebx,%ebx
8048084:       31 c9                   xor    %ecx,%ecx
8048086:       31 d2                   xor    %edx,%edx

8048088:       eb 37                   jmp    80480c1 

0804808a :
804808a:       59                      pop    %ecx
804808b:       88 51 0a                mov    %dl,0xa(%ecx)
804808e:       bb 61 d9 e7 77          mov    $0x77e7d961,%ebx
8048093:       51                      push   %ecx
8048094:       ff d3                   call   *%ebx
8048096:       eb 39                   jmp    80480d1 

08048098 :
8048098:       59                      pop    %ecx
8048099:       31 d2                   xor    %edx,%edx
804809b:       88 51 0b                mov    %dl,0xb(%ecx)
804809e:       51                      push   %ecx
804809f:       50                      push   %eax
80480a0:       bb 32 b3 e7 77          mov    $0x77e7b332,%ebx
80480a5:       ff d3                   call   *%ebx
80480a7:       eb 39                   jmp    80480e2 

080480a9 :
80480a9:       59                      pop    %ecx
80480aa:       31 d2                   xor    %edx,%edx
80480ac:       88 51 03                mov    %dl,0x3(%ecx)
80480af:       31 d2                   xor    %edx,%edx
80480b1:       52                      push   %edx
80480b2:       51                      push   %ecx
80480b3:       51                      push   %ecx
80480b4:       52                      push   %edx
80480b5:       ff d0                   call   *%eax

080480b7 :
80480b7:       31 d2                   xor    %edx,%edx
80480b9:       50                      push   %eax
80480ba:       b8 fd 98 e7 77          mov    $0x77e798fd,%eax
80480bf:       ff d0                   call   *%eax

080480c1 :
80480c1:       e8 c4 ff ff ff          call   804808a 
80480c6:       75 73                   jne    804813b 
80480c8:       65                      gs
80480c9:       72 33                   jb     80480fe 
80480cb:       32 2e                   xor    (%esi),%ch
80480cd:       64                      fs
80480ce:       6c                      insb   (%dx),%es:(%edi)
80480cf:       6c                      insb   (%dx),%es:(%edi)
80480d0:       4e                      dec    %esi

080480d1 :
80480d1:       e8 c2 ff ff ff          call   8048098 
80480d6:       4d                      dec    %ebp
80480d7:       65                      gs
80480d8:       73 73                   jae    804814d 
80480da:       61                      popa  
80480db:       67                      addr16
80480dc:       65                      gs
80480dd:       42                      inc    %edx
80480de:       6f                      outsl  %ds:(%esi),(%dx)
80480df:       78 41                   js     8048122 
80480e1:       4e                      dec    %esi

080480e2 :
80480e2:       e8 c2 ff ff ff          call   80480a9 
80480e7:       48                      dec    %eax
80480e8:       65                      gs
80480e9:       79 4e                   jns    8048139</code>

Now we are almost done. We just have to collect the machine code from the command prompt output.

So our final shell code will looks like...
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x37\x59\x88\x51\x0a\xbb\x61\xd9"\
"\xe7\x77\x51\xff\xd3\xeb\x39\x59\x31\xd2\x88\x51\x0b\x51\x50\xbb\x32"\
"\xb3\xe7\x77\xff\xd3\xeb\x39\x59\x31\xd2\x88\x51\x03\x31\xd2\x52\x51"\
"\x51\x52\xff\xd0\x31\xd2\x50\xb8\xfd\x98\xe7\x77\xff\xd0\xe8\xc4\xff"\
"\xff\xff\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x4e\xe8\xc2\xff\xff"\
"\xff\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x4e\xe8\xc2\xff\xff"\
"\xff\x48\x65\x79\x4e"

To test shell codes the code i use is following...


/*shellcodetest.c*/

char code[] = "opcode will go here!";
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}



Just put your shell code into code[] and compile it with devC++
When you will execute it you should get a message box if everything is fine....

Comments

  1. Thank you so much for sharing all this wonderful information !!!! It is so appreciated!! You have good humor in your blogs. So much helpful and easy to read!
    Java Training in Chennai

    ReplyDelete

Post a Comment