安全中国首页 > 文章中心 > 溢出文章
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

金山词霸的溢出漏洞分析

更新时间:2006-9-7 10:36:02
责任编辑:池天
热 点:
sowhat的漏洞报告http://www.nsfocus.net/vulndb/7069
偶在使用金山词霸的时候也遇到过这种问题,造成系统假死机,本以为真是个溢出问题,或许可以利用利用,写一大段E文诱惑某人来看:),于是在假死机的状态下呼出Softice,发现堆内存被疯狂申请,最终确定只是个内存泄露问题:P,下面给出细节。偶测试的版本是金山词霸2003,点帮助后显示的版本信息为6.0.0.0。

金山词霸主程序xdict.exe负责与其注射到每个进程里的插件(Cjktl32.dll)通信,获取取得的字符,并进行处理。
问题出现在xdict.exe的sub_44e3b0函数中,如下:

.text:0044E3B0           sub   esp, 9Ch
.text:0044E3B6           push   ebp
.text:0044E3B7           push   esi
.text:0044E3B8           push   edi
.text:0044E3B9           mov   edi, ecx
.text:0044E3BB           xor   ebp, ebp
.text:0044E3BD           mov   [esp+0A8h+var_84], edi
.text:0044E3C1           mov   eax, [edi+48h]
.text:0044E3C4           cmp   eax, ebp
.text:0044E3C6           jz     short loc_44E3D7
.text:0044E3C8           mov   eax, [eax]
.text:0044E3CA           cmp   eax, ebp
.text:0044E3CC           jz     short loc_44E3D7
.text:0044E3CE           push   eax               ; BSTR
.text:0044E3CF           call   ds:SysStringLen     ;求取词长度
.text:0044E3D5           jmp   short loc_44E3D9
...
.text:0044E4CA           mov   ecx, edi
.text:0044E4CC           mov   esi, eax
.text:0044E4CE           call   sub_44D560     ;这个call根据取词Buff计算SumTableCode大小
...
.text:0044E578 loc_44E578:                         ; CODE XREF: sub_44E3B0+158j
.text:0044E578           mov   eax, [edi+5D8h]
.text:0044E57E           mov   edx, [esp+0ACh+var_7C]
.text:0044E582           sub   eax, ebp
.text:0044E584           cmp   edx, eax         ;SumTabldeCode与一固定值比较,大于等于则跳
.text:0044E586           jge   short loc_44E5ED
...
...
.text:0044E5ED loc_44E5ED:                         ; CODE XREF: sub_44E3B0+1D6j
.text:0044E5ED           mov   ebp, [esi+38h]
.text:0044E5F0           mov   esi, [esi+3Ch]
.text:0044E5F3           mov   edi, [esp+0ACh+var_94]
.text:0044E5F7           mov   ecx, [esp+0ACh+var_84]
.text:0044E5FB           push   esi
.text:0044E5FC           push   ebp
.text:0044E5FD           push   edi
.text:0044E5FE           push   eax
.text:0044E5FF           mov   [esp+0BCh+var_80], esi
.text:0044E603           call   sub_44E970         ; 拷贝当前取词并拷贝至1堆内存,并取得0x0000结尾,
.text:0044E603                                 ; 正常应返回内存Unicode字节数,异常返回0
.text:0044E608           add   eax, ebp
.text:0044E60A           mov   [esp+0ACh+var_88], eax
.text:0044E60E           lea   ecx, [eax-1]     ;ecx=-1
.text:0044E611           cmp   ecx, esi         ;
.text:0044E613           jge   loc_44E70C     ;小于,不跳
.text:0044E619           mov   [esp+0ACh+var_24], edi
.text:0044E620           jmp   short loc_44E626     ;进入堆内存申请代码
.text:0044E622 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0044E622
.text:0044E622 loc_44E622:                         ; CODE XREF: sub_44E3B0+350j
.text:0044E622           mov   eax, [esp+0ACh+var_88]   ; 进入1次,分配一次堆内存。
.text:0044E626
.text:0044E626 loc_44E626:                         
.text:0044E626           mov   esi, [ebx+8]
.text:0044E629           mov   edx, [esp+0ACh+var_9C]
.text:0044E62D           dec   eax
.text:0044E62E           push   0FFFFFFFFh
.text:0044E630           lea   ecx, [esi+1]
.text:0044E633           mov   [esp+0B0h+var_1C], eax
.text:0044E63A           mov   eax, [esp+0B0h+var_8C]
.text:0044E63E           push   ecx
.text:0044E63F           mov   ecx, ebx
.text:0044E641           mov   [esp+0B4h+var_20], ebp
.text:0044E648           mov   [esp+0B4h+var_18], edx
.text:0044E64F           mov   [esp+0B4h+var_14], eax
.text:0044E656           call   sub_426B60         ; 这个函数分配了堆内存
...
.text:0044E6D8           push   ecx
.text:0044E6D9           mov   [esp+0B0h+var_8C], ebp
.text:0044E6DD           mov   ebp, [esp+0B0h+var_88]
.text:0044E6E1           push   ebp
.text:0044E6E2           push   edi
.text:0044E6E3           push   edx
.text:0044E6E4           mov   ecx, esi
.text:0044E6E6           mov   [esp+0BCh+var_9C], 0
.text:0044E6EE           call   sub_44E970         ; 和0044e603处同样的函数,SumTableCode>0x1f8,返回0
.text:0044E6F3           mov   ecx, [esp+0ACh+var_80]
.text:0044E6F7           add   eax, ebp
.text:0044E6F9           mov   [esp+0ACh+var_88], eax
.text:0044E6FD           dec   eax
.text:0044E6FE           cmp   eax, ecx           ; sub_44e970返回0时eax=-1,跳,构成死循环
.text:0044E700           jl     loc_44E622
.text:0044E706           mov   edi, [esp+0ACh+var_94]
.text:0044E70A           mov   esi, ecx


程序先通过函数sub_44E970遍历取得的每个字符,并根据每个字符计算出一个SumTableCode值,这个值再和一固定值StaticCode相比较,大于等于则会进入sub_44E970子函数,此函数又比较了一遍SumTableCode和StaticCode,大于则认为出错,返回0。主函数在处理这个函数的返回值时出现错误(未考虑返回0的情况,直接减1=-1),导致进入死循环,不断分配堆内存,从而导致内存泄露。

sub_44E970子函数里计算SumTableCode的算法简要:


for (i=0;i<sizeof(plain)-1;i++)
{   
  SumTableCode=SumTableCode+BaseTable[plain*3*4]+BaseTable[plain*3*4+4]+BaseTable[plain*3*4+8]
}

BaseTable为一大数据表(附在后面),plain为取词缓冲区。

也就是说,SumTableCode>StaticCode就会跳到死循环中产生内存泄露,偶的机器的StaticCode恒为0x1f8,查表字符A对应的
  BaseTable[plain*3*4]+BaseTable[plain*3*4+4]+BaseTable[plain*3*4+8]=9
因此要输入至少0x1f8/9+1=57个’A’字符才能触发内存泄露,56个’A’也不会触发。

另外的一个可能是真正的溢出问题出现在其取词插件Cjktl32.dll模块中,由于触发次数有限,暂时还未得到细节:P

附:
dump出来的BaseTable

"\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00"
"\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
"\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00"
"\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00"
"\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
"\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00"
"\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00"
"\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
"\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00"
"\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00"
"\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
"\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00"
"\x01\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
"\x0B\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x0A\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00"
"\x00\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00"
"\x01\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00"
"\x03\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00"
"\x01\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00"
"\x01\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00"
"\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00"
"\x01\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00"
"\x01\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
"\x08\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00"
"\x00\x00\x00\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0A\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x07\x00\x00\x00"
"\x01\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
"\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00"
"\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00"
"\x01\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x0C\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x0B\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00"
"\x00\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
"\x09\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x0B\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x0D\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x0A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0A\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x08\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x03\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00"
"\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00"
"\x01\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
"\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x03\x00\x00\x00"
"\x01\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x0B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x01\x00\x00\x00"
"\x00\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00"
"\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00"
"\x04\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x06\x00\x00\x00"
"\xFF\xFF\xFF\xFF\x08\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00";

 
相关文章
一日一文章
 
一日一软件
一日一动画