之前看了
http://bbs.pediy.com/showthread.php?t=172839,对该漏洞的利用过程还是不是很清楚,加之以前没有研究过内核漏洞,所以想自己调试一下,重现漏洞利用的过程。在调试过程中借鉴了instruder大牛的ppt,小弟水平有限,分析的不对的地方还望多多批评指正。
EPATHOBJ Exploit漏洞调试心得
环境:
物理主机windows 7 32位+windbg
虚拟机 windows xp sp3 32位
该漏洞触发是当PathRecord->next被替换成ExploitRecord,之前的EPATHOBJ__bFlatten 循环就会被终止,调用EPATHOBJ__pprFlattenRec函数,触发任意地址写PathObj对象地址,所以在WatchdogThread函数中下断点,如下图:
调用InterlockedExchange函数将&PathRecord->next指向ExploitRecord,如图:
在0x4010d2处下断点,g命令运行到0x4010d2处,如下图:
Call testSYS+0x1810是调用
LogMessage(L_ERROR, "InterlockedExchange(0x%08x, 0x%08x);", &PathRecord->next, &ExploitRecord);
而0x4010f9处就是kernel32!InterlockedExchange函数,此时堆栈如图:
而0x940000就是PathRecord结构,如图:
此时反汇编win32k!EPATHOBJ::bFlatten,如图:
0xbf8b8b67处下断点,g命令运行到该处,此时eax的数据如图:
0x448e50就是ExploitRecord结构,此时调用0xbf8b8b74处的
win32!EPATHOBJ::pprFlattenRec函数触发任意地址写,这里借用instruder大牛的ppt里面的关于漏洞细节的图片:
win32k!EPATHOBJ::pprFlattenRec:
bf881f0e 8bff mov edi,edi
bf881f10 55 push ebp
bf881f11 8bec mov ebp,esp
bf881f13 81ece0000000 sub esp,0E0h
bf881f19 68ffffff7f push 7FFFFFFFh
bf881f1e 8d45f4 lea eax,[ebp-0Ch]
bf881f21 50 push eax
bf881f22 8d45fc lea eax,[ebp-4]
bf881f25 50 push eax
bf881f26 894df8 mov dword ptr [ebp-8],ecx
bf881f29 e8cf6b0300 call win32k!EPATHOBJ::newpathrec (bf8b8afd)
bf881f2e 83f801 cmp eax,1
bf881f31 0f8553ffffff jne win32k!EPATHOBJ::pprFlattenRec+0x25 (bf881e8a)//不跳转
bf881f37 53 push ebx
bf881f38 56 push esi
bf881f39 8b75fc mov esi,dword ptr [ebp-4] 此时esi就是node
bf881f3c 57 push edi
bf881f3d 8b7d08 mov edi,dword ptr [ebp+8] //edi的值是ExploitRecord地址
bf881f40 8b4704 mov eax,dword ptr [edi+4]
//[edi+4]的值是ExploitRecord. prev
bf881f43 894604 mov dword ptr [esi+4],eax
bf881f46 8d5e0c lea ebx,[esi+0Ch]
bf881f49 832300 and dword ptr [ebx],0
bf881f4c 8b4708 mov eax,dword ptr [edi+8]
//[edi+8]=0x11 就是ExploitRecord.flags = PD_BEZIERS | PD_BEGINSUBPATH
bf881f4f 83e0ef and eax,0FFFFFFEFh
bf881f52 894608 mov dword ptr [esi+8],eax //node->flag
bf881f55 8b4604 mov eax,dword ptr [esi+4] //v6=node->prev
bf881f58 85c0 test eax,eax
bf881f5a 0f8431ffffff je win32k!EPATHOBJ::pprFlattenRec+0x51 (bf881e91)
bf881f60 8930 mov dword ptr [eax],esi //*(dword *)v6 = node触发
此指令运行之前eax的值为:
指令运行之后eax的值为:
可见0x8054683c的数据被写成了0xe204d014,而0xe204d014地址是node结构的地址,数据是我们可以控制的。0x8054683c是HalDispatchTable+0x4处的地址,那么漏洞触发后就覆盖了该处的地址。
继续执行到如图:
mov edi,dword ptr[edi]此时[edi]=0x602464ff,指令执行完后edi=0x602464ff,就是MAGIC_DWORD,也即是jmp [esp+0x60]指令的机器码。
执行完mov dword ptr [esi],edi后,esi地址的结构如图:
此时HalDispatchTable+0x4处数据0xe204d014中的数据已经构造好,通过调用NtQueryIntervalProfile就可以通过jmp [esp+0x60]指令进入NtQueryIntervalProfile第二个参数地址执行(ret = NtQueryIntervalProfile(2, (PULONG)ShellCode)),我们知道NtQueryIntervalProfile函数是通过KeQueryIntervalProfile函数进入ring 0的,所以我们反汇编KeQueryIntervalProfile函数如图:
可见,在KeQueryIntervalProfile函数的内部调用了HalDispatchTable+0x4,我们在此处下断点,g命令运行到该处,F11进入函数调用,如图:
此时esp+0x60的数据为:
正好为调用NtQueryIntervalProfile函数的第二个参数,shellcode地址,此时,通过KeQueryIntervalProfile函数进入ring 0,就实现了在ring 0访问ring 3的地址空间,在ring 0执行shellcode,shellcode所做的工作是改变当前进程的Token,使之具备系统权限,这样就完成了提权工作。
注:本帖由看雪论坛志愿者PEstone 重新将DOC整理排版,若和原文有出入,以原作者附件为准
上传附件:
EPATHOBJ Exploit漏洞调试心得.doc
调试截图.rar
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课