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.....
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…
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...
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....
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....
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!
ReplyDeleteJava Training in Chennai