bug/bundler_fix
jvazquez-r7 2013-03-19 08:52:56 +01:00
commit 7c90d0a125
3 changed files with 269 additions and 8 deletions

View File

@ -65,6 +65,17 @@ class Core
"-w" => [ true, "Specify connect timeout." ],
"-z" => [ false, "Just try to connect, then return." ])
@@grep_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ],
"-i" => [ false, "Ignore case." ],
"-m" => [ true, "Stop after arg matches." ],
"-v" => [ false, "Invert match." ],
"-A" => [ true, "Show arg lines of output After a match." ],
"-B" => [ true, "Show arg lines of output Before a match." ],
"-s" => [ true, "Skip arg lines of output before attempting match."],
"-k" => [ true, "Keep (include) arg lines at start of output." ],
"-c" => [ false, "Only print a count of matching lines." ])
@@search_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
@ -86,6 +97,7 @@ class Core
"color" => "Toggle color",
"exit" => "Exit the console",
"go_pro" => "Launch Metasploit web GUI",
"grep" => "Grep the output of another command",
"help" => "Help menu",
"info" => "Displays information about one or more module",
"irb" => "Drop into irb scripting mode",
@ -236,6 +248,10 @@ class Core
#
# Tab completion for the resource command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_resource_tabs(str, words)
tabs = []
#return tabs if words.length > 1
@ -314,8 +330,8 @@ class Core
driver.destack_dispatcher
# Restore the prompt
prompt = framework.datastore['Prompt'] || "%undmsf%clr "
prompt_char = framework.datastore['PromptChar'] || ">"
prompt = framework.datastore['Prompt'] || Msf::Ui::Console::Driver::DefaultPrompt
prompt_char = framework.datastore['PromptChar'] || Msf::Ui::Console::Driver::DefaultPromptChar
driver.update_prompt("#{prompt}", prompt_char, true)
end
end
@ -671,6 +687,10 @@ class Core
#
# Tab completion for the info command (same as use)
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_info_tabs(str, words)
cmd_use_tabs(str, words)
end
@ -787,6 +807,10 @@ class Core
#
# Tab completion for the jobs command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_jobs_tabs(str, words)
if words.length == 1
return @@jobs_opts.fmt.keys
@ -810,6 +834,13 @@ class Core
cmd_jobs("-k", *args)
end
#
# Tab completion for the kill command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_kill_tabs(str, words)
return [] if words.length > 1
framework.jobs.keys
@ -928,6 +959,10 @@ class Core
#
# Tab completion for the threads command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_threads_tabs(str, words)
if words.length == 1
return @@threads_opts.fmt.keys
@ -1004,6 +1039,10 @@ class Core
#
# Tab completion for the load command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_load_tabs(str, words)
tabs = []
@ -1163,6 +1202,10 @@ class Core
#
# Tab completion for the route command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_route_tabs(str, words)
if words.length == 1
return %w{add remove get flush print}
@ -1285,6 +1328,13 @@ class Core
print(added)
end
#
# Tab completion for the loadpath command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_loadpath_tabs(str, words)
return [] if words.length > 1
@ -1403,6 +1453,13 @@ class Core
print_line(tbl.to_s)
end
#
# Tab completion for the search command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_search_tabs(str, words)
if words.length == 1
return @@search_opts.fmt.keys
@ -1718,6 +1775,10 @@ class Core
#
# Tab completion for the sessions command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_sessions_tabs(str, words)
if words.length == 1
return @@sessions_opts.fmt.keys
@ -1839,6 +1900,10 @@ class Core
#
# Tab completion for the set command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_set_tabs(str, words)
# A value has already been specified
@ -1920,6 +1985,10 @@ class Core
#
# Tab completion for the setg command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_setg_tabs(str, words)
cmd_set_tabs(str, words)
end
@ -2016,6 +2085,10 @@ class Core
#
# Tab completion for the show command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_show_tabs(str, words)
return [] if words.length > 1
@ -2061,6 +2134,10 @@ class Core
#
# Tab completion for the unload command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_unload_tabs(str, words)
return [] if words.length > 1
@ -2134,6 +2211,10 @@ class Core
#
# Tab completion for the unset command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_unset_tabs(str, words)
datastore = active_module ? active_module.datastore : self.framework.datastore
datastore.keys
@ -2158,6 +2239,10 @@ class Core
#
# Tab completion for the unsetg command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_unsetg_tabs(str, words)
self.framework.datastore.keys
end
@ -2239,8 +2324,8 @@ class Core
mod.init_ui(driver.input, driver.output)
# Update the command prompt
prompt = framework.datastore['Prompt'] || "%undmsf%clr "
prompt_char = framework.datastore['PromptChar'] || ">"
prompt = framework.datastore['Prompt'] || Msf::Ui::Console::Driver::DefaultPrompt
prompt_char = framework.datastore['PromptChar'] || Msf::Ui::Console::Driver::DefaultPromptChar
driver.update_prompt("#{prompt} #{mod.type}(%bld%red#{mod.shortname}%clr) ", prompt_char, true)
end
@ -2286,6 +2371,13 @@ class Core
end
end
#
# Tab completion for the pushm command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_pushm_tabs(str, words)
tab_complete_module(str, words)
end
@ -2339,6 +2431,10 @@ class Core
#
# Tab completion for the use command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completd
def cmd_use_tabs(str, words)
return [] if words.length > 1
@ -2361,6 +2457,153 @@ class Core
return true
end
def cmd_grep_help
print_line "Usage: grep [options] pattern cmd"
print_line
print_line "Grep the results of a console command (similar to Linux grep command)"
print(@@grep_opts.usage())
end
#
# Greps the output of another console command, usage is similar the shell grep command
# grep [options] pattern other_cmd [other command's args], similar to the shell's grep [options] pattern file
# however it also includes -k to keep lines and -s to skip lines. grep -k 5 is useful for keeping table headers
#
# @param args [Array<String>] Args to the grep command minimally including a pattern & a command to search
# @return [String,nil] Results matching the regular expression given
def cmd_grep(*args)
return cmd_grep_help if args.length < 2
match_mods = {:insensitive => false}
output_mods = {:count => false, :invert => false}
@@grep_opts.parse(args.dup) do |opt, idx, val|
case opt
when "-h"
return cmd_grep_help
when "-m"
# limit to arg matches
match_mods[:max] = val.to_i
# delete opt and val from args list
args.shift(2)
when "-A"
# also return arg lines after a match
output_mods[:after] = val.to_i
# delete opt and val from args list
args.shift(2)
when "-B"
# also return arg lines before a match
output_mods[:before] = val.to_i
# delete opt and val from args list
args.shift(2)
when "-v"
# invert match
match_mods[:invert] = true
# delete opt from args list
args.shift
when "-i"
# case insensitive
match_mods[:insensitive] = true
args.shift
when "-c"
# just count matches
output_mods[:count] = true
args.shift
when "-k"
# keep arg number of lines at the top of the output, useful for commands with table headers in output
output_mods[:keep] = val.to_i
args.shift(2)
when "-s"
# skip arg number of lines at the top of the output, useful for avoiding undesirable matches
output_mods[:skip] = val.to_i
args.shift(2)
end
end
# after deleting parsed options, the only args left should be the pattern, the cmd to run, and cmd args
pattern = args.shift
if match_mods[:insensitive]
rx = Regexp.new(pattern, true)
else
rx = Regexp.new(pattern)
end
cmd = args.join(" ")
# get a ref to the current console driver
orig_driver = self.driver
# redirect output after saving the old ones and getting a new output buffer to use for redirect
orig_driver_output = orig_driver.output
orig_driver_input = orig_driver.input
# we use a rex buffer but add a write method to the instance, which is required in order to be valid $stdout
temp_output = Rex::Ui::Text::Output::Buffer.new
def temp_output.write(msg = '')
self.print_raw(msg)
end
orig_driver.init_ui(orig_driver_input,temp_output)
# run the desired command to be grepped
orig_driver.run_single(cmd)
# restore original output
orig_driver.init_ui(orig_driver_input,orig_driver_output)
# restore the prompt so we don't get "msf > >".
prompt = framework.datastore['Prompt'] || Msf::Ui::Console::Driver::DefaultPrompt
prompt_char = framework.datastore['PromptChar'] || Msf::Ui::Console::Driver::DefaultPromptChar
mod = active_module
if mod # if there is an active module, give them the fanciness they have come to expect
driver.update_prompt("#{prompt} #{mod.type}(%bld%red#{mod.shortname}%clr) ", prompt_char, true)
else
driver.update_prompt("#{prompt}", prompt_char, true)
end
# dump the command's output so we can grep it
cmd_output = temp_output.dump_buffer
# Bail if the command failed
if cmd_output =~ /Unknown command:/
print_error("Unknown command: #{args[0]}.")
return false
end
# put lines into an array so we can access them more easily and split('\n') doesn't work on the output obj.
all_lines = cmd_output.lines.select {|line| line}
# control matching based on remaining match_mods (:insensitive was already handled)
if match_mods[:invert]
statement = 'not line =~ rx'
else
statement = 'line =~ rx'
end
our_lines = []
count = 0
all_lines.each_with_index do |line, line_num|
next if (output_mods[:skip] and line_num < output_mods[:skip])
our_lines << line if (output_mods[:keep] and line_num < output_mods[:keep])
# we don't wan't to keep processing if we have a :max and we've reached it already (not counting skips/keeps)
break if match_mods[:max] and count >= match_mods[:max]
if eval statement
count += 1
# we might get a -A/after and a -B/before at the same time
our_lines += retrieve_grep_lines(all_lines,line_num,output_mods[:before], output_mods[:after])
end
end
# now control output based on remaining output_mods such as :count
return print_status(count.to_s) if output_mods[:count]
our_lines.each {|line| print line}
end
#
# Tab completion for the grep command
#
# @param str [String] the string currently being typed before tab was hit
# @param words [Array<String>] the previously completed words on the command line. words is always
# at least 1 when tab completion has reached this stage since the command itself has been completed
def cmd_grep_tabs(str, words)
tabs = @@grep_opts.fmt.keys || [] # default to use grep's options
# if not an opt, use normal tab comp.
# @todo uncomment out next line when tab_completion normalization is complete RM7649 or
# replace with new code that permits "nested" tab completion
# tabs = driver.get_all_commands if (str and str =~ /\w/)
tabs
end
#
# Tab complete module names
#
@ -2811,7 +3054,7 @@ class Core
[ 'MinimumRank', framework.datastore['MinimumRank'] || '', 'The minimum rank of exploits that will run without explicit confirmation' ],
[ 'SessionLogging', framework.datastore['SessionLogging'] || '', 'Log all input and output for sessions' ],
[ 'TimestampOutput', framework.datastore['TimestampOutput'] || '', 'Prefix all console output with a timestamp' ],
[ 'Prompt', framework.datastore['Prompt'] || '', 'The prompt string, defaults to "%undmsf%clr"' ],
[ 'Prompt', framework.datastore['Prompt'] || '', 'The prompt string, defaults to "#{Msf::Ui::Console::Driver::DefaultPrompt}"' ],
[ 'PromptChar', framework.datastore['PromptChar'] || '', 'The prompt character, defaults to ">"' ],
[ 'PromptTimeFormat', framework.datastore['PromptTimeFormat'] || '', 'A format for timestamp escapes in the prompt, see ruby\'s strftime docs' ],
].each { |r| tbl << r }
@ -2941,6 +3184,24 @@ class Core
'Columns' => [ 'Name', 'Disclosure Date', 'Rank', 'Description' ]
)
end
#
# Returns an array of lines at the provided line number plus any before and/or after lines requested
# from all_lines by supplying the +before+ and/or +after+ parameters which are always positive
#
# @param all_lines [Array<String>] An array of all lines being considered for matching
# @param line_num [Integer] The line number in all_lines which has satisifed the match
# @param after [Integer] The number of lines after the match line to include (should always be positive)
# @param before [Integer] The number of lines before the match line to include (should always be positive)
# @return [Array<String>] Array of lines including the line at line_num and any +before+ and/or +after+
def retrieve_grep_lines(all_lines,line_num, before = nil, after = nil)
after = after.to_i.abs
before = before.to_i.abs
start = line_num - before
start = 0 if start < 0
finish = line_num + after
return all_lines.slice(start..finish)
end
end

View File

@ -1527,7 +1527,7 @@ class Db
print_error("The database is not connected")
return
end
print_status("Purging and rebuilding the module cache in the background...")
framework.threads.spawn("ModuleCacheRebuild", true) do
framework.db.purge_all_module_details

View File

@ -333,13 +333,13 @@ module DispatcherShell
str = Regexp.escape(str)
end
# XXX - This still doesn't fix some Regexp warnings:
# @todo - This still doesn't fix some Regexp warnings:
# ./lib/rex/ui/text/dispatcher_shell.rb:171: warning: regexp has `]' without escape
# Match based on the partial word
items.find_all { |e|
e =~ /^#{str}/
# Prepend the rest of the command (or it gets replaced!)
# Prepend the rest of the command (or it all gets replaced!)
}.map { |e|
tab_words.dup.push(e).join(' ')
}