Land #8511, console search options
lands sempervictus' console search command enahncements and bug fixesbug/bundler_fix
commit
3a445655ae
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue