Microsoft Windows是一款商业视窗操作系统。 Microsoft Windows winhlp32.exe在解析.hlp文件的时候存在着一个堆溢出,远程攻击者可以利用这个漏洞可能以用户进程权限在系统上执行任意指令。 当hlp文件是以分段来进行压缩的,他包含一个以phrase命名的内部文件,这个phrase文件由一个phrase表头和多个phrase表组成,phrase的表头处于.hlp文件的偏移0x19处,结构定义如下: unsigned short wNumberOfPhrases; unsigned short wOneHundred; 0x0100; long decompressedsize; phrases表头后面立即跟着phrases表,每个phrases表项占4个字节,2个字段phrasesHeadOffset和phrasesEndOffset,分别都是即unsigned short类型。代表phrases的头尾的偏移。 处理phrases表的函数具有3个参数(在中文2000 sp4上该函数的地址是0x0100A1EF),其中第3个参数为指向phrases表头的指针,第2个参数指向一个堆内存,用于保存phrases数据.但是在计算数据长度时并没有判断数据长度是否合法,这就导致可以构造一个.HLP,可以覆盖由第2个参数所指向的堆内存。以下是对该函数的分析: 0100A1EF sub_100A1EF proc near ; CODE XREF: sub_100A14C+6Fp .text:0100A1EF .text:0100A1EF arg_0 = dword ptr 4 .text:0100A1EF arg_4 = dword ptr 8 .text:0100A1EF arg_8 = dword ptr 0Ch .text:0100A1EF .text:0100A1EF mov eax, [esp+arg_8] ;arg_8 指向phrase表头 .text:0100A1F3 push ebx .text:0100A1F4 push esi .text:0100A1F5 push edi .text:0100A1F6 movzx edx, word ptr [eax+2] ;[eax+2] -> wOneHundred...
Microsoft Windows是一款商业视窗操作系统。 Microsoft Windows winhlp32.exe在解析.hlp文件的时候存在着一个堆溢出,远程攻击者可以利用这个漏洞可能以用户进程权限在系统上执行任意指令。 当hlp文件是以分段来进行压缩的,他包含一个以phrase命名的内部文件,这个phrase文件由一个phrase表头和多个phrase表组成,phrase的表头处于.hlp文件的偏移0x19处,结构定义如下: unsigned short wNumberOfPhrases; unsigned short wOneHundred; 0x0100; long decompressedsize; phrases表头后面立即跟着phrases表,每个phrases表项占4个字节,2个字段phrasesHeadOffset和phrasesEndOffset,分别都是即unsigned short类型。代表phrases的头尾的偏移。 处理phrases表的函数具有3个参数(在中文2000 sp4上该函数的地址是0x0100A1EF),其中第3个参数为指向phrases表头的指针,第2个参数指向一个堆内存,用于保存phrases数据.但是在计算数据长度时并没有判断数据长度是否合法,这就导致可以构造一个.HLP,可以覆盖由第2个参数所指向的堆内存。以下是对该函数的分析: 0100A1EF sub_100A1EF proc near ; CODE XREF: sub_100A14C+6Fp .text:0100A1EF .text:0100A1EF arg_0 = dword ptr 4 .text:0100A1EF arg_4 = dword ptr 8 .text:0100A1EF arg_8 = dword ptr 0Ch .text:0100A1EF .text:0100A1EF mov eax, [esp+arg_8] ;arg_8 指向phrase表头 .text:0100A1F3 push ebx .text:0100A1F4 push esi .text:0100A1F5 push edi .text:0100A1F6 movzx edx, word ptr [eax+2] ;[eax+2] -> wOneHundred .text:0100A1FA mov ecx, [eax+0Ch] ;[eax+0Ch] -> phrase 表 .text:0100A1FD mov eax, [esp+0Ch+arg_0] ;以下计算 phrase表的偏移 .text:0100A201 sub eax, edx .text:0100A203 mov ebx, [esp+0Ch+arg_4] .text:0100A207 mov edi, eax .text:0100A209 shr eax, 1 .text:0100A20B and edi, 1 .text:0100A20E movzx edx, word ptr [ecx+eax*2] ;phrase_offset1 .text:0100A212 movzx esi, word ptr [ecx+eax*2+2] ;phrase_offset2 .text:0100A217 sub esi, edx .text:0100A219 add ecx, edx .text:0100A21B push esi ; size_t ;size = phrase_offset2 - phrase_offset1 .text:0100A21C push ecx ; void * .text:0100A21D push ebx ; void * ;ebx -> 第二个参数,即堆内存 .text:0100A21E call ds:memmove 在这里,存在着2个导致溢出的问题: 1.整数溢出,如果phrasesEndOffset比phrasesHeadOffset小,phrasesEndOffset-phrasesHeadOffset为一个负数,这里并没有做检查,实际调用memmove的时候,触发了溢出。 2.另外,在堆分配的时候,并非是根据phrasesEndOffset-phrasesHeadOffset计算时候进行分配的,而是根据hlp文件里的另外字段进行解码计算和分配的,由于解码和计算过程过于复杂,这里不在详细描述,只要修改一个正常的hlp文件的某个phrases表项,增大phrasesEndOffset字段也将触发这一漏洞。