Permalink
Cannot retrieve contributors at this time
# -*- coding: binary -*- | |
module Msf | |
class Post | |
module Windows | |
module WMIC | |
include Msf::Post::File | |
include Msf::Post::Windows::Priv | |
include Msf::Post::Windows::ExtAPI | |
def initialize(info = {}) | |
super | |
register_options([ | |
OptString.new('SMBUser', [ false, 'The username to authenticate as' ]), | |
OptString.new('SMBPass', [ false, 'The password for the specified username' ]), | |
OptString.new('SMBDomain', [ false, 'The Windows domain to use for authentication' ]), | |
OptAddress.new("RHOST", [ true, "Target address range", "localhost" ]), | |
OptInt.new("TIMEOUT", [ true, "Timeout for WMI command in seconds", 10 ]) | |
], self.class) | |
end | |
def wmic_query(query, server=datastore['RHOST']) | |
extapi = load_extapi | |
result_text = "" | |
if datastore['SMBUser'] | |
if server.downcase == "localhost" || server.downcase.starts_with?('127.') | |
raise RuntimeError, "WMIC: User credentials cannot be used for local connections" | |
end | |
end | |
if extapi && !is_system? | |
session.extapi.clipboard.set_text("") | |
wcmd = "wmic #{wmic_user_pass_string}/output:CLIPBOARD /INTERACTIVE:off /node:#{server} #{query}" | |
else | |
tmp = get_env('TEMP') | |
out_file = "#{tmp}\\#{Rex::Text.rand_text_alpha(8)}" | |
wcmd = "cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe #{wmic_user_pass_string}/output:#{out_file} /INTERACTIVE:off /node:#{server} #{query}" | |
end | |
vprint_status("[#{server}] #{wcmd}") | |
# We dont use cmd_exec as WMIC cannot be Channelized | |
ps = session.sys.process.execute(wcmd, nil, {'Hidden' => true, 'Channelized' => false}) | |
session.railgun.kernel32.WaitForSingleObject(ps.handle, (datastore['TIMEOUT'] * 1000)) | |
ps.close | |
if extapi && !is_system? | |
result = session.extapi.clipboard.get_data.first | |
if result && result[1] && result[1].has_key?('Text') | |
result_text = result[1]['Text'] | |
else | |
result_text = "" | |
end | |
else | |
result_text = Rex::Text.to_ascii(read_file(out_file))[1..-1] | |
file_rm(out_file) | |
end | |
return result_text | |
end | |
def wmic_command(cmd, server=datastore['RHOST']) | |
result_text = wmic_query("process call create \"#{cmd.gsub('"','\\"')}\"", server) | |
parsed_result = nil | |
unless result_text.blank? | |
vprint_status("[#{server}] WMIC Command Result:") | |
vprint_line(result_text) | |
parsed_result = parse_wmic_result(result_text) | |
end | |
if parsed_result == nil | |
vprint_error("[#{server}] WMIC Command Error") | |
end | |
return parsed_result | |
end | |
def parse_wmic_result(result_text) | |
if result_text.blank? | |
return nil | |
else | |
pid = nil | |
return_value = nil | |
if result_text =~ /ProcessId = (\d+);/ | |
pid = $1.to_i | |
end | |
if result_text =~ /ReturnValue = (\d+);/ | |
return_value = $1.to_i | |
end | |
return {:return => return_value, :pid => pid, :text =>result_text} | |
end | |
end | |
def wmic_user_pass_string(domain=datastore['SMBDomain'], user=datastore['SMBUser'], pass=datastore['SMBPass']) | |
userpass = "" | |
unless user.nil? | |
if domain.nil? | |
userpass = "/user:\"#{user}\" /password:\"#{pass}\" " | |
else | |
userpass = "/user:\"#{domain}\\#{user}\" /password:\"#{pass}\" " | |
end | |
end | |
return userpass | |
end | |
end # WMIC | |
end # Windows | |
end # Post | |
end # Msf |