Land #9145, ERB/<ruby> for Meterpreter resource
commit
5de190f092
|
@ -59,8 +59,8 @@ module Msf
|
|||
elsif
|
||||
# let's check to see if it's in the scripts/resource dir (like when tab completed)
|
||||
[
|
||||
::Msf::Config.script_directory + ::File::SEPARATOR + "resource",
|
||||
::Msf::Config.user_script_directory + ::File::SEPARATOR + "resource"
|
||||
::Msf::Config.script_directory + ::File::SEPARATOR + 'resource',
|
||||
::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource'
|
||||
].each do |dir|
|
||||
res_path = dir + ::File::SEPARATOR + res
|
||||
if ::File.exist?(res_path)
|
||||
|
@ -97,7 +97,7 @@ module Msf
|
|||
[
|
||||
::Msf::Config.script_directory + File::SEPARATOR + "resource",
|
||||
::Msf::Config.user_script_directory + File::SEPARATOR + "resource",
|
||||
"."
|
||||
'.'
|
||||
].each do |dir|
|
||||
next if not ::File.exist? dir
|
||||
tabs += ::Dir.new(dir).find_all { |e|
|
||||
|
|
|
@ -1530,49 +1530,73 @@ class Console::CommandDispatcher::Core
|
|||
end
|
||||
|
||||
def cmd_resource_help
|
||||
print_line('Usage: resource <path1> [path2 ...]')
|
||||
print_line "Usage: resource path1 [path2 ...]"
|
||||
print_line
|
||||
print_line('Run the commands stored in the supplied files.')
|
||||
print_line "Run the commands stored in the supplied files (- for stdin)."
|
||||
print_line "Resource files may also contain ERB or Ruby code between <ruby></ruby> tags."
|
||||
print_line
|
||||
end
|
||||
|
||||
def cmd_resource(*args)
|
||||
if args.empty?
|
||||
cmd_resource_help
|
||||
return false
|
||||
end
|
||||
|
||||
args.each do |glob|
|
||||
files = ::Dir.glob(::File.expand_path(glob))
|
||||
if files.empty?
|
||||
print_error("No such file #{glob}")
|
||||
next
|
||||
args.each do |res|
|
||||
good_res = nil
|
||||
if res == '-'
|
||||
good_res = res
|
||||
elsif ::File.exist?(res)
|
||||
good_res = res
|
||||
elsif
|
||||
# let's check to see if it's in the scripts/resource dir (like when tab completed)
|
||||
[
|
||||
::Msf::Config.script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter',
|
||||
::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter'
|
||||
].each do |dir|
|
||||
res_path = dir + ::File::SEPARATOR + res
|
||||
if ::File.exist?(res_path)
|
||||
good_res = res_path
|
||||
break
|
||||
end
|
||||
files.each do |filename|
|
||||
print_status("Reading #{filename}")
|
||||
if (not ::File.readable?(filename))
|
||||
print_error("Could not read file #{filename}")
|
||||
next
|
||||
end
|
||||
end
|
||||
if good_res
|
||||
client.console.load_resource(good_res)
|
||||
else
|
||||
::File.open(filename, 'r').each_line do |line|
|
||||
next if line.strip.length < 1
|
||||
next if line[0,1] == '#'
|
||||
begin
|
||||
print_status("Running #{line}")
|
||||
client.console.run_single(line)
|
||||
rescue ::Exception => e
|
||||
print_error("Error Running Command #{line}: #{e.class} #{e}")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
print_error("#{res} is not a valid resource file")
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_resource_tabs(str, words)
|
||||
return [] if words.length > 1
|
||||
|
||||
tab_complete_filenames(str, words)
|
||||
tabs = []
|
||||
#return tabs if words.length > 1
|
||||
if ( str and str =~ /^#{Regexp.escape(::File::SEPARATOR)}/ )
|
||||
# then you are probably specifying a full path so let's just use normal file completion
|
||||
return tab_complete_filenames(str,words)
|
||||
elsif (not words[1] or not words[1].match(/^\//))
|
||||
# then let's start tab completion in the scripts/resource directories
|
||||
begin
|
||||
[
|
||||
::Msf::Config.script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter',
|
||||
::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter',
|
||||
'.'
|
||||
].each do |dir|
|
||||
next if not ::File.exist? dir
|
||||
tabs += ::Dir.new(dir).find_all { |e|
|
||||
path = dir + ::File::SEPARATOR + e
|
||||
::File.file?(path) and ::File.readable?(path)
|
||||
}
|
||||
end
|
||||
rescue Exception
|
||||
end
|
||||
else
|
||||
tabs += tab_complete_filenames(str,words)
|
||||
end
|
||||
return tabs
|
||||
end
|
||||
|
||||
def cmd_enable_unicode_encoding
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
require 'rex/ui'
|
||||
require 'pp'
|
||||
require 'rex/text/table'
|
||||
require 'erb'
|
||||
|
||||
module Rex
|
||||
module Ui
|
||||
|
@ -368,6 +369,73 @@ module DispatcherShell
|
|||
return items
|
||||
end
|
||||
|
||||
# Processes a resource script file for the console.
|
||||
#
|
||||
# @param path [String] Path to a resource file to run
|
||||
# @return [void]
|
||||
def load_resource(path)
|
||||
if path == '-'
|
||||
resource_file = $stdin.read
|
||||
path = 'stdin'
|
||||
elsif ::File.exist?(path)
|
||||
resource_file = ::File.read(path)
|
||||
else
|
||||
print_error("Cannot find resource script: #{path}")
|
||||
return
|
||||
end
|
||||
|
||||
# Process ERB directives first
|
||||
print_status "Processing #{path} for ERB directives."
|
||||
erb = ERB.new(resource_file)
|
||||
processed_resource = erb.result(binding)
|
||||
|
||||
lines = processed_resource.each_line.to_a
|
||||
bindings = {}
|
||||
while lines.length > 0
|
||||
|
||||
line = lines.shift
|
||||
break if not line
|
||||
line.strip!
|
||||
next if line.length == 0
|
||||
next if line =~ /^#/
|
||||
|
||||
# Pretty soon, this is going to need an XML parser :)
|
||||
# TODO: case matters for the tag and for binding names
|
||||
if line =~ /<ruby/
|
||||
if line =~ /\s+binding=(?:'(\w+)'|"(\w+)")(>|\s+)/
|
||||
bin = ($~[1] || $~[2])
|
||||
bindings[bin] = binding unless bindings.has_key? bin
|
||||
bin = bindings[bin]
|
||||
else
|
||||
bin = binding
|
||||
end
|
||||
buff = ''
|
||||
while lines.length > 0
|
||||
line = lines.shift
|
||||
break if not line
|
||||
break if line =~ /<\/ruby>/
|
||||
buff << line
|
||||
end
|
||||
if ! buff.empty?
|
||||
session = client
|
||||
framework = client.framework
|
||||
|
||||
print_status("resource (#{path})> Ruby Code (#{buff.length} bytes)")
|
||||
begin
|
||||
eval(buff, bin)
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception => e
|
||||
print_error("resource (#{path})> Ruby Error: #{e.class} #{e} #{e.backtrace}")
|
||||
end
|
||||
end
|
||||
else
|
||||
print_line("resource (#{path})> #{line}")
|
||||
run_single(line)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Run a single command line.
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue