Win32 Dynamic Shellcode

3 minute read

Enviornment Setup

kernel32.dll

  • See Skape’s paper for full details.
  • Unlike Linux System-Calls, Window’s System-Calls do not support networking.
  • In Window’s, DLL’s are used instead of System-Calls for shellcode.
    • Dynamically-Linking-Librarie’s are mapped into the process’s memory at runtime.
  • The only DLL that is guaranteed to exist in the process is kernel32.dll.

Dynamically Finding kernel32.dll in Process Memory

    xor ecx, ecx            ; clear ecx register
    mov eax, [fs:ecx+0x30]  ; save PEB address in eax register
    mov eax, [eax+0xc]      ; pointer to the loader data structure (Ldr)
    mov esi, [eax+0x1c]     ; first entry in the init order module list
    lodsd                   ; grab next entry which points to kernel32.dll
    mov eax, [eax+0x8]      ; store module base address in eax
    ret                     ; return to caller
  • After executing this code, the program should have the base address of kernel32.dll stored in the eax register.

Compiling + Extracting the Shellcode Hex

root@kali# nasm -f win32 findKernel32.asm -o win32.o
root@kali# for i in $(objdump -D findKernel32.o | grep "^ " | cut -f2); do echo -n '\x'$i;done;echo
\x31\xc9\x64\x8b\x41\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40\x08\xc3
  • Compiled on kali linux x64 host.

Shellcode Test Program

char code[] = "\xcc\x31\xc9\x64\x8b\x41\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40\x08\xc3";
int main(int argc, char **argv)
{
    int (*func)();
    func = (int(*)()) code;
    (int)(*func)();
}
  • Added ‘\xcc’ to start of code[] array to set a software breakpoint.
  • The breakpoint allows us to step through our test code as it executes; using a debugger like Immunity.
  • Compiled on Windows XP SP3 Pro x86 (32-bit), with lcc-win32 program.

Testing the Shellcode Execution

  • Open the compiled program with Immunity Debugger.
  • When pressing the play button, the code should break at our software breakpoint.

  • We see that we successfully found our kernel32.dll base address within the host process’s memory.
  • Our shellcode successfully stores the base address of kernel32.dll in the eax register.
  • In Immunity we verify kernel32’s base address by pressing Alt+M to go to view the memory map, and then find our kernel32.dll base address.
  • we found kernel32.dll at 0x7c800000. Great success!

LoadLibraryA() – within kernel32.dll

  • A function/symbol within the kernel32.dll that can load other DLL’s into the process’s memory.
  • LoadLibraryA() Microsoft Documentation.
    HMODULE LoadLibraryA(LPCSTR lpLibFileName);
    
    lpLibFileName
    The name of the module/DLL to load.

Updated: