High Level Windows Shellcode Development Methods

Heres a super quick entry covering some high level methods you can use when developing Windows shellcode.

The methods are:
  • Using the memory editing features of a debugger
  • Using a c compiler
  • Using an assembler

Using a debugger

Writing shellcode using the code editing features of a debugger like OllyDbg is best suited to really simple (approximately <20 byte) shellcode, or for making small edits to already written code while you are actually testing it.  This method is also great when you want to enter the instruction using an opcode instead of the assembly equivalent, which you may want to do when writing shellcode to work around bad character limitations.

The exploit writers debugger guide I wrote a while ago covers how to write and perform small edits to shellcode using the memory editing features in OllyDbg, and this should also work for Immunity Debugger.  The links are available from here:

Exploit writers debugging tutorial

Using a c compiler

Writing shellcode using a c compiler is a good method for writing more detailed code.  Using Didier Stevens' method, you can also debug your code inside the Visual Studio IDE.  I haven't had the opportunity to use this method myself as yet, but testing this out has been on my ever expanding "To Try" list ever since I first read about it, so I thought I'd link to it here.

The links are available from Didier's blog, here:

http://blog.didierstevens.com/2010/05/04/writing-win32-shellcode-with-a-c-compiler/

Using an assembler

Writing shellcode using an assembler is a fairly obvious method, and was the one I used to develop my Download and Execute Script shellcode.

As an example of how this is done, heres some assembly code I pieced together for another Vulnserver related article I recently wrote (hopefully I'll be posting links to it here any day now).  This code is actually based on code from a SecurityForest article that is now offline, and I think they in turn got it from some older Phrack article...
[BITS 32]

; Shellcode to redirect execution back 768 bytes from instruction following CALL

global _start

jmp short jmpspot   
callspot:        ; The CALL lands here, stack now has address of next instruction
pop ecx            ; pops address of next instruction into ECX
dec ch            ; decrement CH register by 1 = ECX - 256
dec ch
dec ch
jmp ecx            ; jmp to ECX
jmpspot:
call callspot

Save this as shellcode.asm, then assemble to binary form into file shellcode.bin using nasm as follows:

stephen@lion:~$ nasm -f bin shellcode.asm -o shellcode.bin

We can then print this out in Hex format, ready for pasting into an exploit, using command line perl-fu

stephen@lion:~$ cat shellcode.bin | perl -e 'while (read STDIN, $d, 1) {print "\\x" . sprintf( "%02x", ord($d));}; print "\n"'
\x59\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1\xe8\xf2\xff\xff\xff

Or we can get it printed out in slightly neater manner with a character count at the end using my very simple convertsc2h.pl script.

stephen@lion:~$ convertsc2h.pl shellcode.bin
Shellcode:
\x59\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1\xe8\xf2\xff\xff\xff

Length:14