5.3 逆向分析nt!NtAllocateVirtualMemory进入win8内核调试,就要结合静态分析和动态调试来挖掘有用的信息。首先找到win8内核文件。 **需要注意的是此时分析的是虚拟机中**** win8 ****系统的内核文件,不是**** win7 *\*主机的内核文件。** 5.3.1 NtAllocatevirtualMemory参数确认 在前面的调试中,windbg断在了NT! NtAllocatevirtualMemory函数的入口处。对比NtAllocatevirtualMemory函数在windbg和IDA反编译的结果: 可知,在运行完指令call __SEH_prolog4_GS,后EBP+8为第一个参数,EBP+C为第二个参数,那就看看在调用call __SEH_prolog4_GS后EBP的值,如下图: 第一个参数是进程句柄,本进程句柄刚好是-1,第二个参数基地址指针,之前我们在程序中基地址是4,也就是0×00000004,查看基地址指针的值: 刚好是0×00000004,用户态传入的第三个参数是0,这里的第三个参数也刚好是0。其他参数不在一一列举;也就是是说内核函数NtAllocatevirtualMemory与用户态函数zwallocatevirtualmemory参数是一致的。 5.3.2 查找NtAllocatevirtualMemory 零页内存安全机制 到了最重要的时刻,接下来动态调试NtAllocatevirtualMemory, 一路单步执行,看到eax=0xc00000f0时停下: 从图中可知并EAX来自于ESI的赋值。那就继续往上看,看ESI的值是从哪里来的 从图中看出,在执行test[edi+0C4],1000000h指令后,如果相等就执行了mov esi,0xc00000f0。 5.3.3 确认NtAllocatevirtualMemory零页内存安全机制 前面已经找到了返回0xc00000f0的地方,接下来就要看看条件判断的地方, EDI=0x84b2ac80是EPROCESS进程的地址,查看EPROCESS结果可知: 在结构eprocess偏移0xc4的位置刚好是标志Vdmallowed,该值是0,并且[edi=0xc4] 与上1000000后刚好是零。导致ESI=0xc00000f0,进而导致EAX=0xc00000f0。 **到此基本上已经确认了**** NtAllocateVirtualMemory ****中对**** NULLPage ****的安全机制,就是检查**** EPROCESS ****中的**** VdmAllowed *\*的标志位。** 确定条件判断确定位置 从判断语句来看V76应该是参数中的基地址,V14应该是EPROCESS的地址。看一下这两个值的来源 从上图可知v76就是baseaddress; V14追溯到keGetCurrentThread,在内核模式下FS却指向KPCR(Kernel’s Processor Control Region)结构。即FS段的起点与KPCR结构对齐。看一下KPCR结构偏移124的位置 图中可知偏移124的位置刚好的当前线程的结构地址。通过查看函数KeGetCurrentThread的实现也能证实这一点,如下图: 线程结构地址+128(0×80)的位置刚好是当前进程的内核地址,如下图所示: 之后NtAllocateVirtualMemory函数在将进程结构地址偏移0xC4值与0×1000000做比较判断做安全检查。 到目前为止,NtAllocateVirtualMemory函数对零页内存的保护机制剖析完成。总结一下: 判断基地址是否小于**** 0×1000000, 判断内核结构**** EPROCESS ****的**** Vdmallowed ****标志是否为**** 05.3.4 查找内核中其他对零页内存保护的函数 通过对NtAllocateVirtualMemory逆向分析和动态跟踪了解了win8中对零页内存的保护机制;那么除了NtAllocateVirtualMemory函数,在内核中是否还有其他的函数也对零页内存进行了安全检查呢? 通过在整个NT内核文件中查找零页内存保护机制,又发现了几个包含零页内存包含的函数,搜索结果如下图: 也就是说在内核文件中除了NTAllocateVirtualMemory外,还有四个函数对零页内存做检测: MiIsVaRangeAvailable: MiMapViewOfPhySicalSection MiMapLockedPagesInUserSpace MiCreatePebOrTeb这四个函数不都是导出函数,也就是说在内核编程中有可能我们使用的一些导出函数中内部调用了这四个函数中的某一个,其内部已经做了零页内存检测。 6 总结本文先是介绍了什么是空指针漏洞,之后对windows系统的零页内存保护机制做了剖析。 空指针漏洞: 对零页内存的安全防护: 检测分配页是否在零页内存。 **检测**** EPROCESS ****结构中的**** VdmAllowed *\*标志。**Win8**** 以后的零页内存防护也只是保证了不会在零页内存分配空间,缓解分配零页内存空间来利用漏洞;从上图可知,利用零页内存分配导致的空指针漏洞也只是众多空指针漏洞类型中的一种。通过零页内存保护机制并不能缓解所有的空指针漏洞。 |