Skip to content

Commit 3a44565

Browse files
David MaloneyDavid Maloney
authored andcommitted
Land rapid7#8511, console search options
lands sempervictus' console search command enahncements and bug fixes
2 parents 4fdd77f + 42d1fae commit 3a44565

File tree

7 files changed

+150
-73
lines changed

7 files changed

+150
-73
lines changed

lib/msf/ui/console/command_dispatcher/core.rb

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class Core
5151
"-r" => [ false, "Reset the ring buffer for the session given with -i, or all" ],
5252
"-u" => [ true, "Upgrade a shell to a meterpreter session on many platforms" ],
5353
"-t" => [ true, "Set a response timeout (default: 15)" ],
54+
"-S" => [ true, "Row search filter." ],
5455
"-x" => [ false, "Show extended information in the session table" ])
5556

5657
@@threads_opts = Rex::Parser::Arguments.new(
@@ -85,6 +86,10 @@ class Core
8586
"-k" => [ true, "Keep (include) arg lines at start of output." ],
8687
"-c" => [ false, "Only print a count of matching lines." ])
8788

89+
@@search_opts = Rex::Parser::Arguments.new(
90+
"-h" => [ false, "Help banner." ],
91+
"-S" => [ true, "Row search filter." ])
92+
8893
@@history_opts = Rex::Parser::Arguments.new(
8994
"-h" => [ false, "Help banner." ],
9095
"-a" => [ false, "Show all commands in history." ],
@@ -95,7 +100,6 @@ class Core
95100
"-h" => [ false, "Help banner." ],
96101
"-e" => [ true, "Expression to evaluate." ])
97102

98-
99103
# Returns the list of commands supported by this command dispatcher
100104
def commands
101105
{
@@ -171,9 +175,6 @@ def cmd_color(*args)
171175
driver.update_prompt
172176
end
173177

174-
175-
176-
177178
def cmd_cd_help
178179
print_line "Usage: cd <directory>"
179180
print_line
@@ -869,10 +870,12 @@ def cmd_route(*args)
869870

870871
when "add", "remove", "del"
871872
subnet = args.shift
872-
netmask = nil
873-
if subnet
874-
subnet, cidr_mask = subnet.split("/")
875-
netmask = Rex::Socket.addr_ctoa(cidr_mask.to_i) if cidr_mask
873+
subnet,cidr_mask = subnet.split("/")
874+
if Rex::Socket.is_ipv4?(args.first)
875+
netmask = args.shift
876+
else
877+
cidr_mask = '32' if cidr_mask.nil?
878+
netmask = Rex::Socket.addr_ctoa(cidr_mask.to_i)
876879
end
877880

878881
netmask = args.shift if netmask.nil?
@@ -1074,7 +1077,6 @@ def cmd_save(*args)
10741077
print_line("Saved configuration to: #{Msf::Config.config_file}")
10751078
end
10761079

1077-
10781080
def cmd_spool_help
10791081
print_line "Usage: spool <off>|<filename>"
10801082
print_line
@@ -1139,6 +1141,7 @@ def cmd_sessions(*args)
11391141
script = nil
11401142
reset_ring = false
11411143
response_timeout = 15
1144+
search_term = nil
11421145

11431146
# any arguments that don't correspond to an option or option arg will
11441147
# be put in here
@@ -1151,53 +1154,58 @@ def cmd_sessions(*args)
11511154
# Parse the command options
11521155
@@sessions_opts.parse(args) do |opt, idx, val|
11531156
case opt
1154-
when '-q'
1157+
when "-q"
11551158
quiet = true
11561159
# Run a command on all sessions, or the session given with -i
1157-
when '-c'
1160+
when "-c"
11581161
method = 'cmd'
11591162
cmds << val if val
1160-
when '-C'
1163+
when "-C"
11611164
method = 'meterp-cmd'
11621165
cmds << val if val
1163-
when '-x'
1166+
when "-x"
11641167
show_extended = true
1165-
when '-v'
1168+
when "-v"
11661169
verbose = true
11671170
# Do something with the supplied session identifier instead of
11681171
# all sessions.
1169-
when '-i'
1172+
when "-i"
11701173
sid = val
11711174
# Display the list of active sessions
1172-
when '-l'
1175+
when "-l"
11731176
method = 'list'
1174-
when '-k'
1177+
when "-k"
11751178
method = 'kill'
11761179
sid = val || false
1177-
when '-K'
1180+
when "-K"
11781181
method = 'killall'
11791182
# Run a script on all meterpreter sessions
1180-
when '-s'
1183+
when "-s"
11811184
unless script
11821185
method = 'scriptall'
11831186
script = val
11841187
end
11851188
# Upload and exec to the specific command session
1186-
when '-u'
1189+
when "-u"
11871190
method = 'upexec'
11881191
sid = val || false
1192+
# Search for specific session
1193+
when "-S", "--search"
1194+
search_term = val
11891195
# Reset the ring buffer read pointer
1190-
when '-r'
1196+
when "-r"
11911197
reset_ring = true
11921198
method = 'reset_ring'
11931199
# Display help banner
1194-
when '-h'
1200+
when "-h"
11951201
cmd_sessions_help
11961202
return false
1197-
when '-t'
1203+
when "-t"
11981204
if val.to_s =~ /^\d+$/
11991205
response_timeout = val.to_i
12001206
end
1207+
when "-S", "--search"
1208+
search_term = val
12011209
else
12021210
extra << val
12031211
end
@@ -1463,7 +1471,7 @@ def cmd_sessions(*args)
14631471
end
14641472
when 'list',nil
14651473
print_line
1466-
print(Serializer::ReadableText.dump_sessions(framework, :show_extended => show_extended, :verbose => verbose))
1474+
print(Serializer::ReadableText.dump_sessions(framework, :show_extended => show_extended, :verbose => verbose, :search_term => search_term))
14671475
print_line
14681476
end
14691477

@@ -1952,7 +1960,6 @@ def cmd_unsetg_tabs(str, words)
19521960

19531961
alias cmd_unsetg_help cmd_unset_help
19541962

1955-
19561963
#
19571964
# Returns the revision of the framework and console library
19581965
#
@@ -2411,7 +2418,6 @@ def binary_install
24112418
return binary_paths.include? Msf::Config.install_root
24122419
end
24132420

2414-
24152421
#
24162422
# Returns an array of lines at the provided line number plus any before and/or after lines requested
24172423
# from all_lines by supplying the +before+ and/or +after+ parameters which are always positive

lib/msf/ui/console/command_dispatcher/creds.rb

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Creds
1515
include Msf::Ui::Console::CommandDispatcher
1616
include Metasploit::Credential::Creation
1717
include Msf::Ui::Console::CommandDispatcher::Common
18-
18+
1919
#
2020
# The dispatcher's name.
2121
#
@@ -31,11 +31,11 @@ def commands
3131
"creds" => "List all credentials in the database"
3232
}
3333
end
34-
34+
3535
def allowed_cred_types
3636
%w(password ntlm hash)
3737
end
38-
38+
3939
#
4040
# Returns true if the db is connected, prints an error and returns
4141
# false if not.
@@ -51,22 +51,55 @@ def active?
5151
end
5252
true
5353
end
54-
54+
55+
#
56+
# Miscellaneous option helpers
57+
#
58+
59+
# Parse +arg+ into a {Rex::Socket::RangeWalker} and append the result into +host_ranges+
60+
#
61+
# @note This modifies +host_ranges+ in place
62+
#
63+
# @param arg [String] The thing to turn into a RangeWalker
64+
# @param host_ranges [Array] The array of ranges to append
65+
# @param required [Boolean] Whether an empty +arg+ should be an error
66+
# @return [Boolean] true if parsing was successful or false otherwise
67+
def arg_host_range(arg, host_ranges, required=false)
68+
if (!arg and required)
69+
print_error("Missing required host argument")
70+
return false
71+
end
72+
begin
73+
rw = Rex::Socket::RangeWalker.new(arg)
74+
rescue
75+
print_error("Invalid host parameter, #{arg}.")
76+
return false
77+
end
78+
79+
if rw.valid?
80+
host_ranges << rw
81+
else
82+
print_error("Invalid host parameter, #{arg}.")
83+
return false
84+
end
85+
return true
86+
end
87+
5588
#
5689
# Can return return active or all, on a certain host or range, on a
5790
# certain port or range, and/or on a service name.
5891
#
5992
def cmd_creds(*args)
6093
return unless active?
61-
94+
6295
# Short-circuit help
6396
if args.delete "-h"
6497
cmd_creds_help
6598
return
6699
end
67-
100+
68101
subcommand = args.shift
69-
102+
70103
case subcommand
71104
when 'help'
72105
cmd_creds_help
@@ -79,7 +112,7 @@ def cmd_creds(*args)
79112
end
80113

81114
end
82-
115+
83116
#
84117
# TODO: this needs to be cleaned up to use the new syntax
85118
#
@@ -126,7 +159,7 @@ def cmd_creds_help
126159
print_line " creds add user:other hash:d19c32489b870735b5f587d76b934283"
127160
print_line " # Add a NonReplayableHash"
128161
print_line " creds add hash:d19c32489b870735b5f587d76b934283"
129-
162+
130163
print_line
131164
print_line "General options"
132165
print_line " -h,--help Show this help information"
@@ -156,7 +189,7 @@ def cmd_creds_help
156189
print_line " creds -d -s smb"
157190
print_line
158191
end
159-
192+
160193
# @param private_type [Symbol] See `Metasploit::Credential::Creation#create_credential`
161194
# @param username [String]
162195
# @param password [String]
@@ -168,35 +201,35 @@ def creds_add(*args)
168201
hsh[opt[0]] = opt[1..-1].join(':') # everything before the first : is the key, reasembling everything after the colon. why ntlm hashes
169202
hsh
170203
end
171-
204+
172205
begin
173206
params.assert_valid_keys('user','password','realm','realm-type','ntlm','ssh-key','hash','address','port','protocol', 'service-name')
174207
rescue ArgumentError => e
175208
print_error(e.message)
176209
end
177-
210+
178211
# Verify we only have one type of private
179212
if params.slice('password','ntlm','ssh-key','hash').length > 1
180213
private_keys = params.slice('password','ntlm','ssh-key','hash').keys
181214
print_error("You can only specify a single Private type. Private types given: #{private_keys.join(', ')}")
182215
return
183216
end
184-
217+
185218
login_keys = params.slice('address','port','protocol','service-name')
186219
if login_keys.any? and login_keys.length < 3
187220
missing_login_keys = ['host','port','proto','service-name'] - login_keys.keys
188221
print_error("Creating a login requires a address, a port, and a protocol. Missing params: #{missing_login_keys}")
189222
return
190223
end
191-
224+
192225
data = {
193226
workspace_id: framework.db.workspace,
194227
origin_type: :import,
195228
filename: 'msfconsole'
196229
}
197-
230+
198231
data[:username] = params['user'] if params.key? 'user'
199-
232+
200233
if params.key? 'realm'
201234
if params.key? 'realm-type'
202235
if Metasploit::Model::Realm::Key::SHORT_NAMES.key? params['realm-type']
@@ -235,7 +268,7 @@ def creds_add(*args)
235268
data[:private_type] = :nonreplayable_hash
236269
data[:private_data] = params['hash']
237270
end
238-
271+
239272
begin
240273
if login_keys.any?
241274
data[:address] = params['address']
@@ -250,7 +283,7 @@ def creds_add(*args)
250283
print_error("Failed to add #{data['private_type']}: #{e}")
251284
end
252285
end
253-
286+
254287
def creds_search(*args)
255288
host_ranges = []
256289
origin_ranges = []
@@ -264,6 +297,7 @@ def creds_search(*args)
264297
cred_table_columns = [ 'host', 'origin' , 'service', 'public', 'private', 'realm', 'private_type' ]
265298
user = nil
266299
delete_count = 0
300+
search_term = nil
267301

268302
while (arg = args.shift)
269303
case arg
@@ -314,6 +348,8 @@ def creds_search(*args)
314348
return
315349
end
316350
arg_host_range(hosts, origin_ranges)
351+
when '-S', '--search-term'
352+
search_term = args.shift
317353
else
318354
# Anything that wasn't an option is a host to search for
319355
unless (arg_host_range(arg, host_ranges))
@@ -343,7 +379,8 @@ def creds_search(*args)
343379
svcs.flatten!
344380
tbl_opts = {
345381
'Header' => "Credentials",
346-
'Columns' => cred_table_columns
382+
'Columns' => cred_table_columns,
383+
'SearchTerm' => search_term
347384
}
348385

349386
tbl = Rex::Text::Table.new(tbl_opts)
@@ -481,8 +518,8 @@ def cmd_creds_tabs(str, words)
481518
end
482519
return tabs
483520
end
484-
485-
521+
522+
486523
end
487524

488525
end end end end

0 commit comments

Comments
 (0)