Foxmail 5远程缓冲区溢出漏洞
作者: root (webmaster_at_xfocus.org)
注:本文是2004年2月xfocus成员在内部技术交流中提出的,在此之前,启明星辰技术人员已经发现这一漏洞,但未公开细节,xfocus成员听说存在这一漏洞后对Foxmail进行分析,并写出利用代码。2004年3月18日启明星辰公布漏洞并发布相关补丁。
测试环境:win2k sp4+foxmail 5.0.300
以前测试foxmail 4.x的时候曾经发现过溢出漏洞,不过后来一直没时间研究就先放下了,后来听说Foxmail5也有溢出,但是一直没有看见公布。于是没事的时候干脆自己研究一下,测试后发现以前的溢出漏洞已经补上了,不过出了一个新的漏洞。
问题出在PunyLib.dll里面的UrlToLocal函数,估计这是一个用来处理垃圾邮件的链接库,当一封邮件被判定为垃圾邮件时,就会调用UrlToLocal来处理邮件体的“From:
”字段,处理过程中发生堆栈溢出,可以导致执行任意代码。
具体处理过程如下:
.text:10002040
public UrlToLocal
.text:10002040 UrlToLocal proc near
.text:10002040
.text:10002040 arg_0
= dword ptr 4
.text:10002040 arg_4
= dword ptr 8
.text:10002040
.text:10002040
mov eax, dword_1000804C
.text:10002045
mov ecx, dword_10008030
.text:1000204B
mov edx, [esp+arg_4]
.text:1000204F
push offset aHttp ; "_blank">http://"
.text:10002054
push eax
.text:10002055
mov eax, [esp+8+arg_0]
.text:10002059
push offset unk_10008034
.text:1000205E
push ecx
.text:1000205F
push edx
.text:10002060
push eax
.text:10002061
call sub_10002070 ;调用10002070,其中参数里保存的是邮件体的“From:
”字段后面的内容
.text:10002070 sub_10002070 proc near
; CODE XREF: UrlToLocal+21p
.text:10002070
; EmailAdrToLocal+107p
.text:10002070
.text:10002070 var_600 = dword
ptr -600h
.text:10002070 var_500 = dword
ptr -500h
.text:10002070 var_400 = dword
ptr -400h
.text:10002070 var_300 = dword
ptr -300h
.text:10002070 var_200 = dword
ptr -200h
.text:10002070 var_100 = dword
ptr -100h
.text:10002070 arg_0
= dword ptr 4
.text:10002070 arg_4
= dword ptr 8
.text:10002070 arg_8
= dword ptr 0Ch
.text:10002070 arg_C
= dword ptr 10h
.text:10002070 arg_10 =
dword ptr 14h
.text:10002070 arg_14 =
dword ptr 18h
.text:10002070
.text:10002070
mov edx, [esp+arg_0]
.text:10002074
sub esp, 600h
......
.text:100020DF
push eax
.text:100020E0
push ecx
.text:100020E1
push ebx
.text:100020E2
call sub_10001A30 ;调用10001A30,就是这个函数里面溢出了
.text:10001A30 sub_10001A30 proc near
; CODE XREF: sub_10002070+72p
.text:10001A30
; sub_10002290+95p
.text:10001A30
.text:10001A30 var_104 = dword
ptr -104h
.text:10001A30 var_100 = dword
ptr -100h
.text:10001A30 arg_0
= dword ptr 4
.text:10001A30 arg_4
= dword ptr 8
.text:10001A30 arg_8
= dword ptr 0Ch
.text:10001A30 arg_C
= dword ptr 10h
.text:10001A30 arg_10 =
dword ptr 14h
.text:10001A30 arg_14 =
dword ptr 18h
.text:10001A30
.text:10001A30
sub esp, 104h ;分配0x104字节大小的堆栈,但是拷贝的“From:
”字段最大为0x200
.text:10001A36
push ebx
.text:10001A37
mov ebx, [esp+108h+arg_0]
.text:10001A3E
push ebp
.text:10001A3F
mov ebp, [esp+10Ch+arg_10]
.text:10001A46
push esi
.text:10001A47
xor esi, esi
......
.text:10001AA9
sub edi, ecx
.text:10001AAB
mov eax, ecx
.text:10001AAD
mov esi, edi
.text:10001AAF
mov edi, edx
.text:10001AB1
shr ecx, 2
.text:10001AB4
rep movsd ;这里进行内存拷贝的时候溢出了,按照“From:
”字段大小拷贝到0x104的缓冲区里
.text:10001AB6
mov ecx, eax
.text:10001AB8
and ecx, 3
.text:10001ABB