Land #8511, console search options

lands sempervictus' console search command
enahncements and bug fixes
bug/bundler_fix
David Maloney 2017-06-22 12:07:10 -05:00
commit 3a445655ae
No known key found for this signature in database
GPG Key ID: DEDBA9DC3A913DB2
7 changed files with 150 additions and 73 deletions

View File

@ -51,6 +51,7 @@ class Core
"-r" => [ false, "Reset the ring buffer for the session given with -i, or all" ],
"-u" => [ true, "Upgrade a shell to a meterpreter session on many platforms" ],
"-t" => [ true, "Set a response timeout (default: 15)" ],
"-S" => [ true, "Row search filter." ],
"-x" => [ false, "Show extended information in the session table" ])
@@threads_opts = Rex::Parser::Arguments.new(
@ -85,6 +86,10 @@ class Core
"-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." ],
"-S" => [ true, "Row search filter." ])
@@history_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ],
"-a" => [ false, "Show all commands in history." ],
@ -95,7 +100,6 @@ class Core
"-h" => [ false, "Help banner." ],
"-e" => [ true, "Expression to evaluate." ])
# Returns the list of commands supported by this command dispatcher
def commands
{
@ -171,9 +175,6 @@ class Core
driver.update_prompt
end
def cmd_cd_help
print_line "Usage: cd <directory>"
print_line
@ -869,10 +870,12 @@ class Core
when "add", "remove", "del"
subnet = args.shift
netmask = nil
if subnet
subnet, cidr_mask = subnet.split("/")
netmask = Rex::Socket.addr_ctoa(cidr_mask.to_i) if cidr_mask
subnet,cidr_mask = subnet.split("/")
if Rex::Socket.is_ipv4?(args.first)
netmask = args.shift
else
cidr_mask = '32' if cidr_mask.nil?
netmask = Rex::Socket.addr_ctoa(cidr_mask.to_i)
end
netmask = args.shift if netmask.nil?
@ -1074,7 +1077,6 @@ class Core
print_line("Saved configuration to: #{Msf::Config.config_file}")
end
def cmd_spool_help
print_line "Usage: spool <off>|<filename>"
print_line
@ -1139,6 +1141,7 @@ class Core
script = nil
reset_ring = false
response_timeout = 15
search_term = nil
# any arguments that don't correspond to an option or option arg will
# be put in here
@ -1151,53 +1154,58 @@ class Core
# Parse the command options
@@sessions_opts.parse(args) do |opt, idx, val|
case opt
when '-q'
when "-q"
quiet = true
# Run a command on all sessions, or the session given with -i
when '-c'
when "-c"
method = 'cmd'
cmds << val if val
when '-C'
when "-C"
method = 'meterp-cmd'
cmds << val if val
when '-x'
when "-x"
show_extended = true
when '-v'
when "-v"
verbose = true
# Do something with the supplied session identifier instead of
# all sessions.
when '-i'
when "-i"
sid = val
# Display the list of active sessions
when '-l'
when "-l"
method = 'list'
when '-k'
when "-k"
method = 'kill'
sid = val || false
when '-K'
when "-K"
method = 'killall'
# Run a script on all meterpreter sessions
when '-s'
when "-s"
unless script
method = 'scriptall'
script = val
end
# Upload and exec to the specific command session
when '-u'
when "-u"
method = 'upexec'
sid = val || false
# Search for specific session
when "-S", "--search"
search_term = val
# Reset the ring buffer read pointer
when '-r'
when "-r"
reset_ring = true
method = 'reset_ring'
# Display help banner
when '-h'
when "-h"
cmd_sessions_help
return false
when '-t'
when "-t"
if val.to_s =~ /^\d+$/
response_timeout = val.to_i
end
when "-S", "--search"
search_term = val
else
extra << val
end
@ -1463,7 +1471,7 @@ class Core
end
when 'list',nil
print_line
print(Serializer::ReadableText.dump_sessions(framework, :show_extended => show_extended, :verbose => verbose))
print(Serializer::ReadableText.dump_sessions(framework, :show_extended => show_extended, :verbose => verbose, :search_term => search_term))
print_line
end
@ -1952,7 +1960,6 @@ class Core
alias cmd_unsetg_help cmd_unset_help
#
# Returns the revision of the framework and console library
#
@ -2411,7 +2418,6 @@ class Core
return binary_paths.include? Msf::Config.install_root
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

View File

@ -52,6 +52,39 @@ class Creds
true
end
#
# Miscellaneous option helpers
#
# Parse +arg+ into a {Rex::Socket::RangeWalker} and append the result into +host_ranges+
#
# @note This modifies +host_ranges+ in place
#
# @param arg [String] The thing to turn into a RangeWalker
# @param host_ranges [Array] The array of ranges to append
# @param required [Boolean] Whether an empty +arg+ should be an error
# @return [Boolean] true if parsing was successful or false otherwise
def arg_host_range(arg, host_ranges, required=false)
if (!arg and required)
print_error("Missing required host argument")
return false
end
begin
rw = Rex::Socket::RangeWalker.new(arg)
rescue
print_error("Invalid host parameter, #{arg}.")
return false
end
if rw.valid?
host_ranges << rw
else
print_error("Invalid host parameter, #{arg}.")
return false
end
return true
end
#
# Can return return active or all, on a certain host or range, on a
# certain port or range, and/or on a service name.
@ -264,6 +297,7 @@ class Creds
cred_table_columns = [ 'host', 'origin' , 'service', 'public', 'private', 'realm', 'private_type' ]
user = nil
delete_count = 0
search_term = nil
while (arg = args.shift)
case arg
@ -314,6 +348,8 @@ class Creds
return
end
arg_host_range(hosts, origin_ranges)
when '-S', '--search-term'
search_term = args.shift
else
# Anything that wasn't an option is a host to search for
unless (arg_host_range(arg, host_ranges))
@ -343,7 +379,8 @@ class Creds
svcs.flatten!
tbl_opts = {
'Header' => "Credentials",
'Columns' => cred_table_columns
'Columns' => cred_table_columns,
'SearchTerm' => search_term
}
tbl = Rex::Text::Table.new(tbl_opts)

View File

@ -93,7 +93,9 @@ class Db
def cmd_workspace(*args)
return unless active?
search_term = nil
::ActiveRecord::Base.connection_pool.with_connection {
search_term = nil
while (arg = args.shift)
case arg
when '-h','--help'
@ -107,8 +109,10 @@ class Db
delete_all = true
when '-r','--rename'
renaming = true
when '-v'
when '-v','--verbose'
verbose = true
when '-S', '--search'
search_term = args.shift
else
names ||= []
names << arg
@ -178,19 +182,26 @@ class Db
workspace = framework.db.workspace
unless verbose
framework.db.workspaces.each do |ws|
pad = (ws == workspace) ? '* ' : ' '
print_line("#{pad}#{ws.name}")
current = nil
framework.db.workspaces.sort_by {|s| s.name}.each do |s|
if s.name == workspace.name
current = s.name
else
print_line(" #{s.name}")
end
end
print_line("%red* #{current}%clr") unless current.nil?
return
end
workspace = framework.db.workspace
col_names = %w{current name hosts services vulns creds loots notes}
tbl = Rex::Text::Table.new(
'Header' => 'Workspaces',
'Columns' => col_names,
'SortIndex' => -1
'SortIndex' => -1,
'SearchTerm' => search_term
)
# List workspaces
@ -455,11 +466,16 @@ class Db
return
end
cp_hsh = {}
col_names.map do |col|
cp_hsh[col] = { 'MaxChar' => 52 }
end
# If we got here, we're searching. Delete implies search
tbl = Rex::Text::Table.new(
{
'Header' => "Hosts",
'Columns' => col_names,
'ColProps' => cp_hsh,
'SortIndex' => order_by
})
@ -526,7 +542,12 @@ class Db
rhosts << addr
end
if mode == [:delete]
begin
host.destroy
rescue # refs suck
print_error("Forcibly deleting #{host.address}")
host.delete
end
delete_count += 1
end
end
@ -1488,6 +1509,8 @@ class Db
print_status("Usage: db_nmap [--save | [--help | -h]] [nmap options]")
return
end
save = false
arguments = []
while (arg = args.shift)
case arg
@ -1590,7 +1613,7 @@ class Db
print_error(err_line.strip)
end
tabs
return tabs
end
#

View File

@ -34,7 +34,8 @@ module Msf
"-K" => [ false, "Terminate all running jobs." ],
"-i" => [ true, "Lists detailed information about a running job."],
"-l" => [ false, "List all running jobs." ],
"-v" => [ false, "Print more detailed info. Use with -i and -l" ]
"-v" => [ false, "Print more detailed info. Use with -i and -l" ],
"-S" => [ true, "Row search filter." ],
)
def commands
@ -151,6 +152,9 @@ module Msf
# so we can check for the verbose flag.
dump_info = true
job_id = val
when "-S", "--search"
search_term = val
dump_list = true
when "-h"
cmd_jobs_help
return false

View File

@ -22,7 +22,8 @@ module Msf
DISCLOSURE_DATE_FORMAT = "%Y-%m-%d"
@@search_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner."]
"-h" => [ false, "Help banner."],
"-S" => [ true, "Row search filter."],
)
def commands
@ -381,15 +382,20 @@ module Msf
#
def cmd_search(*args)
match = ''
search_term = nil
@@search_opts.parse(args) { |opt, idx, val|
case opt
when "-t"
print_error("Deprecated option. Use type:#{val} instead")
cmd_search_help
return
when "-S", "--search"
search_term = val
when "-h"
cmd_search_help
return
when "-S"
search_term = val
else
match += val + " "
end
@ -397,7 +403,7 @@ module Msf
if framework.db
if framework.db.migrated && framework.db.modules_cached
search_modules_sql(match)
search_modules_sql(match, search_term)
return
else
print_warning("Module database cache not built yet, using slow search")
@ -406,7 +412,7 @@ module Msf
print_warning("Database not connected, using slow search")
end
tbl = generate_module_table("Matching Modules")
tbl = generate_module_table("Matching Modules", search_term)
[
framework.exploits,
framework.auxiliary,
@ -434,8 +440,8 @@ module Msf
#
# @param (see Msf::DBManager#search_modules)
# @return [void]
def search_modules_sql(search_string)
tbl = generate_module_table("Matching Modules")
def search_modules_sql(search_string, search_term = nil)
tbl = generate_module_table("Matching Modules", search_term)
framework.db.search_modules(search_string).each do |o|
tbl << [ o.fullname, o.disclosure_date.nil? ? "" : o.disclosure_date.strftime(DISCLOSURE_DATE_FORMAT), RankingName[o.rank].to_s, o.name ]
end
@ -1157,13 +1163,14 @@ module Msf
print(tbl.to_s)
end
def generate_module_table(type) # :nodoc:
def generate_module_table(type, search_term = nil) # :nodoc:
Table.new(
Table::Style::Default,
'Header' => type,
'Prefix' => "\n",
'Postfix' => "\n",
'Columns' => [ 'Name', 'Disclosure Date', 'Rank', 'Description' ]
'Columns' => [ 'Name', 'Disclosure Date', 'Rank', 'Description' ],
'SearchTerm' => search_term
)
end

View File

@ -288,7 +288,7 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Db do
it "should list default workspace" do
db.cmd_workspace
expect(@output).to match_array [
"* default"
"%red* default%clr"
]
end
@ -298,7 +298,7 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Db do
db.cmd_workspace
expect(@output).to match_array [
" default",
"* foo"
"%red* foo%clr"
]
end
end

View File

@ -22,7 +22,7 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Modules do
end
it 'should generate Matching Modules table' do
expect(core).to receive(:generate_module_table).with('Matching Modules').and_call_original
expect(core).to receive(:generate_module_table).with('Matching Modules', nil).and_call_original
search_modules_sql
end