刚发的写得太潦草了,特地修改一下,如果还是有问题的话,欢迎继续提出~~
早就想分析一下传说中的长老漏洞,不过因为开学的原因,各种事情,一直没有时间,这两天抽时间把漏洞的分析做完了,本来还计划研究一下利用代码和补丁,但是现在不得不放弃了,现把自己的分析过程贴出来,逆向和语文能力都不怎么样,有描述不清之处,请见谅,同时欢迎各位大牛拍砖,但请尽量温柔!
以下内容全部是个人理解,无法保证其正确性,仅供参考!!!
测试环境:Windows 7
测试工具:VMWare + Windbg + IDA
首先下载漏洞的利用程序,在虚拟机中测试一下,发现程序可以正常运行:
代码:
C:\>whoami q-test\qever C:\>poc C:\>whoami nt authority\system
为了减少工作量,应该尽可能地确定漏洞产生的准确位置,在这里采用的方法是在poc的源代码的shellcode起始位置添加0xcc,对应的是"int 3"指令,这样shellcode一运行,就会立刻断下来,然后就可以进行分析了。
修改过程就不废话了,直接运行修改后的程序,当windbg断下来之后,查看调用堆栈,却发现调用堆栈被破坏了
代码:
kd> k ChildEBP RetAddr WARNING: Frame IP not in any known module. Following frames may be wrong. 00000000 00000000 0x3d0000
代码:
kd> k ChildEBP RetAddr WARNING: Frame IP not in any known module. Following frames may be wrong. 92639d14 994bb8d0 0x3d0096 92639d28 83c7f42a win32k!GreEnableEUDC+0x7c 92639d28 772964f4 nt!KiFastCallEntry+0x12a
为了减少工作量,这里采用了一种比较笨的方法,多次尝试来准确判定出错原因及位置。过程如下:
在win32k!GreEnableEUDC处下断点,运行修改后的程序,然后单步跟踪,直至触发shellcode中"int 3"指令,多次尝试之后可以确定如下调用信息:
代码:
win32k!GreEnableEUDC+0x77 : call win32k!BuildAndLoadLinkedFontRoutine+0xeb win32k!BuildAndLoadLinkedFontRoutine+0x19d : call win32k!bAppendSysDirectory+0x209 win32k!bAppendSysDirectory+0x334 : ret 8 //出错!
结合网上的信息,多次尝试后可以确定整个漏洞的产生流程:
代码:
nt!KiFastCallEntry+0x128 : call ebx (win32k!GreEnableEUDC) win32k!GreEnableEUDC+0x77 : call win32k!BuildAndLoadLinkedFontRoutine+0xeb win32k!BuildAndLoadLinkedFontRoutine+0x19d : call win32k!bAppendSysDirectory+0x209 win32k!bAppendSysDirectory+0x2de : call dword ptr [win32k!_imp__RtlQueryRegistryValues (9972f104)] nt!RtlQueryRegistryValues+0x318 : call nt!RtlpCallQueryRegistryRoutine (83e2ab81) nt!RtlpCallQueryRegistryRoutine+0x290 : call nt!RtlpQueryRegistryDirect (83e33997) nt!RtlpQueryRegistryDirect+3D : call nt!memcpy (83c797a0) //溢出 win32k!bAppendSysDirectory+0x334 : ret 8 //出错!
接下来我们挨个来分析以上函数,实际分析过程中是Windbg动态调试和IDA静态分析同时进行的,在此为了书写方便,仅对Windbg代码进行分析。
对于win32k!GreEnableEUDC,涉及到一些不知道什么意思的变量,不过并不影响分析过程。
代码:
win32k!GreEnableEUDC+0x37: 9956b88b 33f6 xor esi,esi //esi清零 9956b88d 46 inc esi //esi == 1 …… win32k!GreEnableEUDC+0x75: 9956b8c9 56 push esi //参数压栈 9956b8ca 56 push esi //参数压栈 9956b8cb e8b8faffff call win32k!BuildAndLoadLinkedFontRoutine+0xeb (9956b388)
这个函数应该是对应poc源码中的EnableEUDC(TRUE);一句,EUDC就不解释了,因为没找到好的中文资料,附上微软的介绍:
http://msdn.microsoft.com/zh-cn/library/ms900737.aspx
根据前面的分析,要关注win32k!BuildAndLoadLinkedFontRoutine+0xeb函数,所以这里重点列出该函数的两个参数,均为1。
下面来看BuildAndLoadLinkedFontRoutine+0xeb函数,这个函数中也没有什么重点内容,依旧是列出参数,和调用语句。
代码:
995cb393 be08020000 mov esi,208h 995cb398 56 push esi 995cb399 8d4dfc lea ecx,[ebp-4] 995cb39c e8a6030000 call win32k!MALLOCOBJ::MALLOCOBJ (995cb747) //生成MALLOCOBJ对象 …… 995cb3aa 8b5dfc mov ebx,dword ptr [ebp-4] …… 995cb434 6804010000 push 104h 995cb439 53 push ebx 995cb43a e8a0050000 call win32k!bAppendSysDirectory+0x209 (995cb9df)
关于win32k!MALLOCOBJ,个人感觉就像一个字符串的类,而在整个漏洞分析过程中,该对象也是扮演了一个字符串的角色,同时在内存起始位置记录了字符串信息。
下面这个win32k!bAppendSysDirectory+0x209函数就比较关键了,最终出错也是在这个函数当中,先看代码:
代码:
win32k!bAppendSysDirectory+0x209: 9955b9df 8bff mov edi,edi 9955b9e1 55 push ebp 9955b9e2 8bec mov ebp,esp 9955b9e4 83ec20 sub esp,20h 9955b9e7 53 push ebx 9955b9e8 56 push esi 9955b9e9 57 push edi 9955b9ea be08020000 mov esi,208h 9955b9ef 56 push esi 9955b9f0 8d4df4 lea ecx,[ebp-0Ch] //ebp-0Ch为MALLOCOBJ对象指针 9955b9f3 e84ffdffff call win32k!MALLOCOBJ::MALLOCOBJ (9955b747) 9955b9f8 56 push esi 9955b9f9 8d4dfc lea ecx,[ebp-4] //ebp-4为MALLOCOBJ对象指针 9955b9fc e846fdffff call win32k!MALLOCOBJ::MALLOCOBJ (9955b747) 9955ba01 8b4df4 mov ecx,dword ptr [ebp-0Ch] 9955ba04 33f6 xor esi,esi //esi == 0 9955ba06 3bce cmp ecx,esi 9955ba08 0f84e6000000 je win32k!bAppendSysDirectory+0x31e (9955baf4) win32k!bAppendSysDirectory+0x238: 9955ba0e 8b7dfc mov edi,dword ptr [ebp-4] 9955ba11 3bfe cmp edi,esi 9955ba13 0f84db000000 je win32k!bAppendSysDirectory+0x31e (9955baf4) win32k!bAppendSysDirectory+0x243: 9955ba19 33c0 xor eax,eax 9955ba1b 8975f0 mov dword ptr [ebp-10h],esi 9955ba1e 8975ec mov dword ptr [ebp-14h],esi 9955ba21 668901 mov word ptr [ecx],ax 9955ba24 668907 mov word ptr [edi],ax 9955ba27 668945e0 mov word ptr [ebp-20h],ax 9955ba2b b804010000 mov eax,104h 9955ba30 50 push eax 9955ba31 8bd0 mov edx,eax 9955ba33 57 push edi 9955ba34 8975e8 mov dword ptr [ebp-18h],esi 9955ba37 668955e2 mov word ptr [ebp-1Eh],dx 9955ba3b 894de4 mov dword ptr [ebp-1Ch],ecx 9955ba3e e8d7feffff call win32k!GrePolyPolyline+0xa2 (9955b91a) //返回"\REGISTRY\USER\S-1-5-18\EUDC\936" 9955ba43 3bc6 cmp eax,esi 9955ba45 8945f8 mov dword ptr [ebp-8],eax 9955ba48 7c7c jl win32k!bAppendSysDirectory+0x2f0 (9955bac6)
代码:
win32k!bAppendSysDirectory+0x274: 9955ba4a 8d45e8 lea eax,[ebp-18h] 9955ba4d 50 push eax 9955ba4e 8d45ec lea eax,[ebp-14h] 9955ba51 50 push eax 9955ba52 8d45f0 lea eax,[ebp-10h] 9955ba55 50 push eax 9955ba56 57 push edi 9955ba57 e850010000 call win32k!AutoResource<&ExFreePool>::~AutoResource<&ExFreePool>+0x177 (9955bbac) 9955ba5c 85c0 test eax,eax 9955ba5e 745f je win32k!bAppendSysDirectory+0x2e9 (9955babf) win32k!bAppendSysDirectory+0x28a: 9955ba60 3975e8 cmp dword ptr [ebp-18h],esi 9955ba63 745a je win32k!bAppendSysDirectory+0x2e9 (9955babf)
代码:
win32k!bAppendSysDirectory+0x28f: 9955ba65 56 push esi 9955ba66 56 push esi 9955ba67 68e0887599 push offset win32k!SharedQueryTable (997588e0) 9955ba6c 57 push edi //"\REGISTRY\USER\S-1-5-18\EUDC\936" 9955ba6d 8d45e0 lea eax,[ebp-20h] 9955ba70 56 push esi 9955ba71 8935e0887599 mov dword ptr [win32k!SharedQueryTable (997588e0)],esi //0 9955ba77 c705e488759924000000 mov dword ptr [win32k!SharedQueryTable+0x4 (997588e4)],24h //24h 9955ba81 c705e888759964a67399 mov dword ptr [win32k!SharedQueryTable+0x8 (997588e8)],offset win32k!`string' (9973a664) //"SystemDefaultEUDCFont" 9955ba8b a3ec887599 mov dword ptr [win32k!SharedQueryTable+0xc (997588ec)],eax //指向函数栈的指针,最终出错也是因为这个参数 9955ba90 8935f0887599 mov dword ptr [win32k!SharedQueryTable+0x10 (997588f0)],esi //0 9955ba96 8935f4887599 mov dword ptr [win32k!SharedQueryTable+0x14 (997588f4)],esi //0 9955ba9c 8935f8887599 mov dword ptr [win32k!SharedQueryTable+0x18 (997588f8)],esi //0 9955baa2 8935fc887599 mov dword ptr [win32k!SharedQueryTable+0x1c (997588fc)],esi //0 9955baa8 893500897599 mov dword ptr [win32k!SharedQueryTable+0x20 (99758900)],esi //0 9955baae 893504897599 mov dword ptr [win32k!SharedQueryTable+0x24 (99758904)],esi //0 9955bab4 ff1504f17299 call dword ptr [win32k!_imp__RtlQueryRegistryValues (9972f104)]
代码:
NTSTATUS RtlQueryRegistryValues( IN ULONG RelativeTo, IN PCWSTR Path, IN PRTL_QUERY_REGISTRY_TABLE QueryTable, IN PVOID Context, IN PVOID Environment OPTIONAL );
代码:
typedef struct _RTL_QUERY_REGISTRY_TABLE { PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine; ULONG Flags; PWSTR Name; PVOID EntryContext; ULONG DefaultType; PVOID DefaultData; ULONG DefaultLength; } RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
Name值为"SystemDefaultEUDCFont",即要查询的内容。DefaultType会存储查询结果,其值为ebp-20h。其余参数为0。
事实上,对于了解RtlQueryRegistryValues函数的人来说,看到这里就已经知道问题所在了,但是作为一次漏洞分析,如果仅仅止步于此的话,并不足以说明问题,按就让我们接着看下去吧!
下面是RtlQueryRegistryValues函数,这个函数内容比较多,分段来解释:
代码:
kd> uf nt!RtlQueryRegistryValues nt!RtlQueryRegistryValues: 83e32d85 8bff mov edi,edi 83e32d87 55 push ebp 83e32d88 8bec mov ebp,esp 83e32d8a 83e4f8 and esp,0FFFFFFF8h 83e32d8d 83ec4c sub esp,4Ch 83e32d90 8b4d0c mov ecx,dword ptr [ebp+0Ch] //exc == Path 83e32d93 53 push ebx 83e32d94 56 push esi 83e32d95 8b7508 mov esi,dword ptr [ebp+8] //esi == RelativeTo 83e32d98 57 push edi 83e32d99 8d442420 lea eax,[esp+20h] //eax == ebp - 0x3c esp == 9240fc30 83e32d9d 50 push eax 83e32d9e 33ff xor edi,edi //edi == 0 83e32da0 57 push edi 83e32da1 8bd6 mov edx,esi //edx == RelativeTo 83e32da3 e89f0a0000 call nt!RtlpGetRegistryHandle (83e33847) //打开"\REGISTRY\USER\S-1-5-18\EUDC\936"返回,返回值放入[ebp - 0x3c](KeyHandle) 83e32da8 3bc7 cmp eax,edi //eax ntStatus 83e32daa 8944240c mov dword ptr [esp+0Ch],eax //ebp=9240fc8c esp=9240fc30 83e32dae 0f8cf7030000 jl nt!RtlQueryRegistryValues+0x426 (83e331ab) 0
代码:
nt!RtlQueryRegistryValues+0x2f: 83e32db4 8974242c mov dword ptr [esp+2Ch],esi // esp + 2c == ebp - 30 83e32db8 8164242c00000040 and dword ptr [esp+2Ch],40000000h 83e32dc0 8d442438 lea eax,[esp+38h] // esp + 38 == ebp - 24 83e32dc4 7505 jne nt!RtlQueryRegistryValues+0x46 (83e32dcb) nt!RtlQueryRegistryValues+0x41: 83e32dc6 ff750c push dword ptr [ebp+0Ch] 83e32dc9 eb01 jmp nt!RtlQueryRegistryValues+0x47 (83e32dcc) //nt!RtlQueryRegistryValues+0x46: //83e32dcb 57 push edi nt!RtlQueryRegistryValues+0x47: 83e32dcc 50 push eax //ebp - 24 83e32dcd e81661e4ff call nt!RtlInitUnicodeString (83c78ee8) //ebp - 24 == Unicode_String_Path 83e32dd2 8d44240c lea eax,[esp+0Ch] //eax == ebp-50 status 83e32dd6 50 push eax 83e32dd7 57 push edi 83e32dd8 8d74242c lea esi,[esp+2Ch] //esi == ebp-38 83e32ddc c744242c84000000 mov dword ptr [esp+2Ch],84h 83e32de4 e8d782ffff call nt!RtlpAllocDeallocQueryBuffer (83e2b0c0) //用esi传参,函数内执行ExAllocatePoolWithTag(1,0x84,0x76727152) 83e32de9 8bf0 mov esi,eax //esi指向申请空间首地址 83e32deb 3bf7 cmp esi,edi 83e32ded 7518 jne nt!RtlQueryRegistryValues+0x82 (83e32e07)
代码:
nt!RtlQueryRegistryValues+0x82: 83e32e07 8b5d10 mov ebx,dword ptr [ebp+10h] //ebx == QueryTable 83e32e0a 897e08 mov dword ptr [esi+8],edi 83e32e0d 8b442420 mov eax,dword ptr [esp+20h] //eax == KeyHandle 83e32e11 c744242882000000 mov dword ptr [esp+28h],82h //ebp - 34 83e32e19 8944241c mov dword ptr [esp+1Ch],eax //ebp - 40 nt!RtlQueryRegistryValues+0x98: 83e32e1d 8b0b mov ecx,dword ptr [ebx] //ecx == QueryTable->QueryRoutine 83e32e1f 3bcf cmp ecx,edi 83e32e21 750a jne nt!RtlQueryRegistryValues+0xa8 (83e32e2d) nt!RtlQueryRegistryValues+0x9e: 83e32e23 f6430421 test byte ptr [ebx+4],21h // byte ptr [ebx+4] = 21h 83e32e27 0f8446030000 je nt!RtlQueryRegistryValues+0x3ee (83e33173) nt!RtlQueryRegistryValues+0xa8: 83e32e2d 8b4304 mov eax,dword ptr [ebx+4] 83e32e30 a820 test al,20h 83e32e32 7419 je nt!RtlQueryRegistryValues+0xc8 (83e32e4d) nt!RtlQueryRegistryValues+0xaf: 83e32e34 397b08 cmp dword ptr [ebx+8],edi 83e32e37 0f841b030000 je nt!RtlQueryRegistryValues+0x3d3 (83e33158) nt!RtlQueryRegistryValues+0xb8: 83e32e3d a801 test al,1 83e32e3f 0f8513030000 jne nt!RtlQueryRegistryValues+0x3d3 (83e33158) nt!RtlQueryRegistryValues+0xc0: 83e32e45 3bcf cmp ecx,edi 83e32e47 0f850b030000 jne nt!RtlQueryRegistryValues+0x3d3 (83e33158) nt!RtlQueryRegistryValues+0xc8: 83e32e4d a803 test al,3 83e32e4f 7418 je nt!RtlQueryRegistryValues+0xe4 (83e32e69) nt!RtlQueryRegistryValues+0xe4: 83e32e69 8b4b04 mov ecx,dword ptr [ebx+4] //ecx == QueryTable->Flags 83e32e6c 8b4308 mov eax,dword ptr [ebx+8] //eax == QueryTable->Name 83e32e6f f6c101 test cl,1 83e32e72 0f8438010000 je nt!RtlQueryRegistryValues+0x22b (83e32fb0) 1 nt!RtlQueryRegistryValues+0x22b: 83e32fb0 3bc7 cmp eax,edi 83e32fb2 0f8417010000 je nt!RtlQueryRegistryValues+0x34a (83e330cf) nt!RtlQueryRegistryValues+0x233: 83e32fb8 50 push eax 83e32fb9 8d442434 lea eax,[esp+34h] 83e32fbd 50 push eax 83e32fbe e8255fe4ff call nt!RtlInitUnicodeString (83c78ee8) 83e32fc3 897c2414 mov dword ptr [esp+14h],edi nt!RtlQueryRegistryValues+0x242: 83e32fc7 8b442414 mov eax,dword ptr [esp+14h] 83e32fcb ff442414 inc dword ptr [esp+14h] 83e32fcf 83f804 cmp eax,4 83e32fd2 0f8f8a010000 jg nt!RtlQueryRegistryValues+0x3dd (83e33162)
代码:
nt!RtlQueryRegistryValues+0x253: 83e32fd8 8d442410 lea eax,[esp+10h] //eax == ebp-4c 83e32fdc 50 push eax //ebp - 4c 83e32fdd ff74242c push dword ptr [esp+2Ch] //0x82 83e32fe1 8d442438 lea eax,[esp+38h] // 83e32fe5 56 push esi //通过nt!RtlpAllocDeallocQueryBuffer申请空间的内存空间首地址 83e32fe6 6a01 push 1 //1 83e32fe8 50 push eax //ebp-2c 83e32fe9 ff742430 push dword ptr [esp+30h] //KeyHandle 83e32fed e86a9ee4ff call nt!ZwQueryValueKey (83c7ce5c) 83e32ff2 8944240c mov dword ptr [esp+0Ch],eax 83e32ff6 bf230000c0 mov edi,0C0000023h 83e32ffb 3d05000080 cmp eax,80000005h 83e33000 7504 jne nt!RtlQueryRegistryValues+0x281 (83e33006)
根据nt!ZwQueryValueKey的参数,可以得知返回的信息为KEY_VALUE_FULL_INFORMATION结构,其定义如下:
代码:
typedef struct _KEY_VALUE_FULL_INFORMATION { ULONG TitleIndex; ULONG Type; ULONG DataOffset; ULONG DataLength; ULONG NameLength; WCHAR Name[1]; // Variable size } KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
代码:
nt!RtlQueryRegistryValues+0x281: 83e33006 33c0 xor eax,eax 83e33008 3944240c cmp dword ptr [esp+0Ch],eax 83e3300c 7d69 jge nt!RtlQueryRegistryValues+0x2f2 (83e33077) nt!RtlQueryRegistryValues+0x2f2: 83e33077 837e0407 cmp dword ptr [esi+4],7 83e3307b 750e jne nt!RtlQueryRegistryValues+0x306 (83e3308b) nt!RtlQueryRegistryValues+0x306: 83e3308b 8b442428 mov eax,dword ptr [esp+28h] 83e3308f ff7514 push dword ptr [ebp+14h] //Context == 0 83e33092 89442414 mov dword ptr [esp+14h],eax 83e33096 53 push ebx //QueryTable 83e33097 8d4c2418 lea ecx,[esp+18h] //ebp-4c == 0x82 83e3309b 8bc6 mov eax,esi //esi指向申请内存空间 83e3309d e8df7affff call nt!RtlpCallQueryRegistryRoutine (83e2ab81)
其参数为nt!RtlQueryRegistryValues函数的参数Context和QueryTable,以及储存前面返回的键值信息的内存空间指针。
接下来看nt!RtlpCallQueryRegistryRoutine函数:
代码:
nt!RtlpCallQueryRegistryRoutine+0xc8: 83e2ac49 8b7e08 mov edi,dword ptr [esi+8] 83e2ac4c 8b4604 mov eax,dword ptr [esi+4] 83e2ac4f 03fe add edi,esi 83e2ac51 8b760c mov esi,dword ptr [esi+0Ch] 83e2ac54 894508 mov dword ptr [ebp+8],eax 83e2ac57 eb7b jmp nt!RtlpCallQueryRegistryRoutine+0x153 (83e2acd4)
代码:
nt!RtlpCallQueryRegistryRoutine+0x282: 83e2ae03 ff730c push dword ptr [ebx+0Ch] //QueryTable->EntryContext 83e2ae06 f6c120 test cl,20h 83e2ae09 7436 je nt!RtlpCallQueryRegistryRoutine+0x2c0 (83e2ae41) nt!RtlpCallQueryRegistryRoutine+0x28a: 83e2ae0b 8b5508 mov edx,dword ptr [ebp+8] //edx的值为KEY_VALUE_FULL_INFORMATION结构中的Type值 83e2ae0e 57 push edi //edi指向KEY_VALUE_FULL_INFORMATION结构中的Name 83e2ae0f 8bc6 mov eax,esi //eax的值为KEY_VALUE_FULL_INFORMATION结构中的DataLength值 83e2ae11 e8818b0000 call nt!RtlpQueryRegistryDirect (83e33997)
这个函数对传进来的参数做了一定的处理,然后传给nt!RtlpQueryRegistryDirect函数,上面有较详细的注释,这个应该就不用多说了吧。
然后是nt!RtlpQueryRegistryDirect函数:
代码:
kd> uf nt!RtlpQueryRegistryDirect nt!RtlpQueryRegistryDirect: 83e33997 8bff mov edi,edi 83e33999 55 push ebp 83e3399a 8bec mov ebp,esp 83e3399c 53 push ebx 83e3399d 8b5d08 mov ebx,dword ptr [ebp+8] 83e339a0 56 push esi 83e339a1 8b750c mov esi,dword ptr [ebp+0Ch] //esi == QueryTable->EntryContext 83e339a4 57 push edi 83e339a5 83fa01 cmp edx,1 83e339a8 7445 je nt!RtlpQueryRegistryDirect+0x56 (83e339ef) nt!RtlpQueryRegistryDirect+0x13: 83e339aa 83fa02 cmp edx,2 83e339ad 7440 je nt!RtlpQueryRegistryDirect+0x56 (83e339ef) nt!RtlpQueryRegistryDirect+0x18: 83e339af 83fa07 cmp edx,7 83e339b2 743b je nt!RtlpQueryRegistryDirect+0x56 (83e339ef) nt!RtlpQueryRegistryDirect+0x1d: 83e339b4 83f804 cmp eax,4 83e339b7 770c ja nt!RtlpQueryRegistryDirect+0x2c (83e339c5) nt!RtlpQueryRegistryDirect+0x22: 83e339b9 3bf3 cmp esi,ebx 83e339bb 7476 je nt!RtlpQueryRegistryDirect+0x9a (83e33a33) nt!RtlpQueryRegistryDirect+0x26: 83e339bd 85c0 test eax,eax 83e339bf 7510 jne nt!RtlpQueryRegistryDirect+0x38 (83e339d1) nt!RtlpQueryRegistryDirect+0x2a: 83e339c1 eb70 jmp nt!RtlpQueryRegistryDirect+0x9a (83e33a33) nt!RtlpQueryRegistryDirect+0x2c: 83e339c5 8b0e mov ecx,dword ptr [esi] 83e339c7 85c9 test ecx,ecx 83e339c9 7d13 jge nt!RtlpQueryRegistryDirect+0x45 (83e339de) nt!RtlpQueryRegistryDirect+0x45: 83e339de 8d7808 lea edi,[eax+8] 83e339e1 3bcf cmp ecx,edi 83e339e3 725d jb nt!RtlpQueryRegistryDirect+0xa9 (83e33a42)
代码:
nt!RtlpQueryRegistryDirect+0x4c: 83e339e5 8906 mov dword ptr [esi],eax //esi指向win32k!bAppendSysDirectory+0x209函数的栈空间 83e339e7 895604 mov dword ptr [esi+4],edx //溢出!,edx的值为KEY_VALUE_FULL_INFORMATION结构中的Type值 83e339ea 83c608 add esi,8 83e339ed ebe2 jmp nt!RtlpQueryRegistryDirect+0x38 (83e339d1) nt!RtlpQueryRegistryDirect+0x38: 83e339d1 50 push eax //eax的值为KEY_VALUE_FULL_INFORMATION结构中DataLength值 83e339d2 53 push ebx //ebx指向KEY_VALUE_FULL_INFORMATION结构中的Name 83e339d3 56 push esi //QueryTable->EntryContext + 8 83e339d4 e8c75de4ff call nt!memcpy (83c797a0) //溢出!
通过上面的代码可以看到,栈溢出了!如果要利用的话,需要计算偏移量,然后修改“\REGISTRY\USER\S-1-5-18\EUDC\936\SystemDefaultEUDCFont”键值的信息,将函数的返回地址覆盖为shellcode的地址。