Land #9145, ERB/<ruby> for Meterpreter resource
commit
5de190f092
|
@ -59,8 +59,8 @@ module Msf
|
||||||
elsif
|
elsif
|
||||||
# let's check to see if it's in the scripts/resource dir (like when tab completed)
|
# 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.script_directory + ::File::SEPARATOR + 'resource',
|
||||||
::Msf::Config.user_script_directory + ::File::SEPARATOR + "resource"
|
::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource'
|
||||||
].each do |dir|
|
].each do |dir|
|
||||||
res_path = dir + ::File::SEPARATOR + res
|
res_path = dir + ::File::SEPARATOR + res
|
||||||
if ::File.exist?(res_path)
|
if ::File.exist?(res_path)
|
||||||
|
@ -97,7 +97,7 @@ module Msf
|
||||||
[
|
[
|
||||||
::Msf::Config.script_directory + File::SEPARATOR + "resource",
|
::Msf::Config.script_directory + File::SEPARATOR + "resource",
|
||||||
::Msf::Config.user_script_directory + File::SEPARATOR + "resource",
|
::Msf::Config.user_script_directory + File::SEPARATOR + "resource",
|
||||||
"."
|
'.'
|
||||||
].each do |dir|
|
].each do |dir|
|
||||||
next if not ::File.exist? dir
|
next if not ::File.exist? dir
|
||||||
tabs += ::Dir.new(dir).find_all { |e|
|
tabs += ::Dir.new(dir).find_all { |e|
|
||||||
|
|
|
@ -1530,49 +1530,73 @@ class Console::CommandDispatcher::Core
|
||||||
end
|
end
|
||||||
|
|
||||||
def cmd_resource_help
|
def cmd_resource_help
|
||||||
print_line('Usage: resource <path1> [path2 ...]')
|
print_line "Usage: resource path1 [path2 ...]"
|
||||||
print_line
|
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
|
print_line
|
||||||
end
|
end
|
||||||
|
|
||||||
def cmd_resource(*args)
|
def cmd_resource(*args)
|
||||||
if args.empty?
|
if args.empty?
|
||||||
|
cmd_resource_help
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
args.each do |glob|
|
args.each do |res|
|
||||||
files = ::Dir.glob(::File.expand_path(glob))
|
good_res = nil
|
||||||
if files.empty?
|
if res == '-'
|
||||||
print_error("No such file #{glob}")
|
good_res = res
|
||||||
next
|
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
|
end
|
||||||
files.each do |filename|
|
end
|
||||||
print_status("Reading #{filename}")
|
end
|
||||||
if (not ::File.readable?(filename))
|
if good_res
|
||||||
print_error("Could not read file #{filename}")
|
client.console.load_resource(good_res)
|
||||||
next
|
|
||||||
else
|
else
|
||||||
::File.open(filename, 'r').each_line do |line|
|
print_error("#{res} is not a valid resource file")
|
||||||
next if line.strip.length < 1
|
next
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def cmd_resource_tabs(str, words)
|
def cmd_resource_tabs(str, words)
|
||||||
return [] if words.length > 1
|
tabs = []
|
||||||
|
#return tabs if words.length > 1
|
||||||
tab_complete_filenames(str, words)
|
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
|
end
|
||||||
|
|
||||||
def cmd_enable_unicode_encoding
|
def cmd_enable_unicode_encoding
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
require 'rex/ui'
|
require 'rex/ui'
|
||||||
require 'pp'
|
require 'pp'
|
||||||
require 'rex/text/table'
|
require 'rex/text/table'
|
||||||
|
require 'erb'
|
||||||
|
|
||||||
module Rex
|
module Rex
|
||||||
module Ui
|
module Ui
|
||||||
|
@ -368,6 +369,73 @@ module DispatcherShell
|
||||||
return items
|
return items
|
||||||
end
|
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.
|
# Run a single command line.
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue