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 0x30
00000002 (01) 5e POP ESI
; Use DB 0x64; 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+0x8]
0000000e (04) 807e1c18 CMP BYTE [ESI+0x1c], 0x18
00000012 (02) 8b36 MOV ESI, [ESI]
00000014 (02) 75f5 JNZ 0xb
The tricky part was how to read from FS:0x30, 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.
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]
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…
Yes, but it looks more like the old way using lodsd. :-)
How do you get the fs:lodsd thing to assemble in FASM ?
As the original snippet suggested,
use:
DB 0×64; LODSD
Hi arkon,
site looks very nice.
my 2 explaining papers
PEB 64
http://sites.google.com/site/x64lab/home/notes-on-x64-windows-gui-programming/exploring-peb-process-environment-block
and custom GetProcAdress
https://sites.google.com/site/x64lab/home/notes-on-x64-windows-gui-programming/customizing-the-getprocaddress
Cheers,
Hi Arkon, a 15 byte version
PUSHL $0x30
POPL %esi
LODSL %fs:(%esi), %eax
MOVL 0x0C(%eax), %eax
MOVL 0x1C(%eax), %esi
LODSL
; Here 0x08(%eax) will contain the address of kernel
PUSHL 0x08(%eax)
…. Use -0x4(%ebp) for access to the module
nasm does not like LODS EAX, [FS:ESI] so one should keep only the LODS.
Agustin, your code will fail if kernel32 is in the place you expect it, and that happen ITW.