Shellcode Tutorial 1: Introduction and Tools Setup
The assembly tutorials contained within this site are aimed towards creating assembly code in the aim to get you ready to create your own assembly and shellcode - which would hopefully be included with the "Project Shellcode Development Framework".
What are the differences between windows shellcode and Linux shellcode?
Linux, unlike windows, provides a direct way to interface with the kernel through the int 0x80 interface. A complete listing of the Linux syscall table can be found at http://www.informatik.htw-dresden.de/~beck/ASM/syscall_list.html. 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. Windows programmers did this so that they could make any change needed to the kernel without any hassle; Linux on the contrary has fixed numbering system for all kernel level functions, and if they were to change, there would be a million angry programmers (and a lot of broken code).
So, what about windows? How do I find the addresses of my needed DLL functions? Don't these addresses change with every service pack upgrade?
There are multitudes of ways to find the addresses of the functions that you need to use in your shellcode. There are two methods for addressing functions; you can find the desired function at runtime or use hard coded addresses. This tutorial will mostly discuss the hard coded method. The only DLL that is guaranteed to be mapped into the shellcode's address space is kernel32.dll. This DLL will hold LoadLibrary and GetProcAddress, the two functions needed to obtain any functions address that can be mapped into the exploits process space. There is a problem with this method though, the address offsets will change with every new release of Windows (service packs, patches etc.). So, if you use this method your shellcode will ONLY work for a specific version of Windows.
Dynamically finding function addresses will be addressed in a later tutorial.
Lets setup your environment!
Initially we will be focusing on creating Windows assembly; however, Linux is really handy for developing assembly and shellcode. For this reason I found Cygwin a great platform to develop shellcode and also be able to access Windows DLLs.
So download and run the Cygwin installer from http://www.cygwin.com/setup.exe
(Project Shellcode Download: http://www.projectshellcode.com/downloads/cygwin_setup.exe)
During the Cygwin installation you will be asked to select which packages you wish to install. The following packages are handy for creating assembly and shellcode.
- Devel->binutils (contains ld, as, objdump)
Once you have your Cygwin environment setup, download the following tools. Some are my own scripts to make things easier, and the last two from external sources. You will want to save them within your Cygwin environment, so copy them to something like C:\cygwin\home\Administrator\shellcode\, where Administrator is your username, and I have created a "shellcode directory" to be our working directory.
Parses xxd output to extract raw shellcode
Automatically compiles the assembly code, extracts the raw shellcode, creates a Unicode encoded version of the raw shellcode, injects your encoded shellcode into a "Template Exploit" (ms07-004) for testing, creates a C test program containing your shellcode, and then compiles it ready to execute! Very Handy!
- or -
Finds which DLLs on your system contain a specific Windows function
(Project Shellcode Download: http://www.projectshellcode.com/downloads/shellcodetest.c)
Start up a bash shell from the start menu and cd to your "shellcode directory", such as;
You now need to compile arwin.c by using the following command;
gcc -o arwin arwin.c
You should now be able to run arwin by typing ./arwin to display the usage information.
We don't need to compile shellcodetest.c at this stage. Once we have created our shellcode, we then place the shellcode into shellcodetest.c and compile it. This allows us to run shellcodetest to execute our shellcode.
The Metasploit Framework is an awesome resource for shellcoding. At the time of writing, the Metasploit team are about to release version Framework 3.3, which runs in a cygwin environment on Windows. The development version can be downloaded via the following link (please let me know if this link becomes broken):
- Metasploit Framework 3.3-dev
(Project Shellcode Download: http://www.projectshellcode.com/downloads/framework-3.3-dev.exe)
This version of the framework gets installed into C:\msf3\ and has its own dedicated cygwin environment. You can launch a shell via shell.bat.
There are also some awesome Windows programs that we will start to use in Tutorial 4, so download the following tools:
- OllyDbg 1.10 (Awesome Windows Debugger)
(Project Shellcode Download: http://www.projectshellcode.com/downloads/odbg110.zip)
- lcc-win32 (Free Windows C Compiler)
(Project Shellcode Download: http://www.projectshellcode.com/downloads/lccwin32.exe)
You are now ready to create your first simple piece of shellcode.