Finding Kernel32 Base Address Shellcode

Yet another one…
This time, smaller, more correct, and still null-free.
I looked a bit at some shellcodes at exploit-db and googled too, to see whether anyone got a smaller way to no avail.

I based my code on:
http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/
AFAIK, who based his post on:
http://blog.harmonysecurity.com/2009_06_01_archive.html

And this is my version:

00000000 (02) 6a30                     PUSH 0×30
00000002 (01) 5e                       POP ESI
; Use DB 0×64; LODSD
00000003 (02) 64ad                     LODS EAX, [FS:ESI]
00000005 (03) 8b700c                   MOV ESI, [EAX+0xc]
00000008 (03) 8b761c                   MOV ESI, [ESI+0x1c]
0000000b (03) 8b5608                   MOV EDX, [ESI+0×8]
0000000e (04) 807e1c18                 CMP BYTE [ESI+0x1c], 0×18
00000012 (02) 8b36                     MOV ESI, [ESI]
00000014 (02) 75f5                     JNZ 0xb
 

The tricky part was how to read from FS:0×30, and the way I use is the smallest one, at least from what I checked.
Another issue that was fixed is the check for kernel32.dll, usually the variation of this shellcode checks for a null byte, but it turned out to be bogous on W2k machines, so it was changed to check for a null word. Getting the shellcode by a byte or two longer.

This way, it’s only 22 bytes, it doesn’t assume that kernel32.dll is the second/third entry in the list, it actually loops till it finds the correct module length (len of ‘kernel32.dll’ * 2 bytes). Also since kernelbase.dll can come first and that renders lots of implementations of this technique unusable.
And obviously the resulting base address of kernel32.dll is in EDX.

Enjoy

[Update July 9th:]
Here’s a link to an explanation about PEB/LDR lists.
See first comment for a better version which is only 17 bytes.

6 Responses to “Finding Kernel32 Base Address Shellcode”

  1. Peter Ferrie says:

    but it does assume that kernel32.dll is the first one whose name is that long. Old style, Win7-compatible, 17 bytes:

    push 30h
    pop esi
    fs:lodsd
    mov eax, [eax+0ch]
    mov esi, [eax+0ch]
    lodsd
    xchg esi, eax
    lodsd
    mov edx, [eax+18h]

  2. arkon says:

    What a RAPE Peter. InLoadedOrder list proved to be better.
    By the way, the xchg/lods could be mov eax, [eax], still 2 bytes, more readable…

  3. Peter Ferrie says:

    Yes, but it looks more like the old way using lodsd. :-)

  4. FASM says:

    How do you get the fs:lodsd thing to assemble in FASM ?

  5. arkon says:

    As the original snippet suggested,
    use:
    DB 0×64; LODSD

Leave a Reply