Skip to content

Commit 52596ae

Browse files
author
kernelsmith
committed
add -R capability like hosts -R
moves the set_rhosts method def out into a separate file so it can be included by both db.rb cmd_hosts and core.rb cmd_grep
1 parent b1dbbe3 commit 52596ae

File tree

3 files changed

+65
-41
lines changed

3 files changed

+65
-41
lines changed

lib/msf/core/set_rhosts.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#
2+
# Set RHOSTS in the +active_module+'s (or global if none) datastore from an array of addresses
3+
#
4+
# This stores all the addresses to a temporary file and utilizes the
5+
# <pre>file:/tmp/filename</pre> syntax to confer the addrs. +rhosts+
6+
# should be an Array. NOTE: the temporary file is *not* deleted
7+
# automatically.
8+
#
9+
def set_rhosts_from_addrs(rhosts)
10+
if rhosts.empty?
11+
print_status "The list is empty, cowardly refusing to set RHOSTS"
12+
return
13+
end
14+
if active_module
15+
mydatastore = active_module.datastore
16+
else
17+
# if there is no module in use set the list to the global variable
18+
mydatastore = self.framework.datastore
19+
end
20+
21+
if rhosts.length > 5
22+
# Lots of hosts makes 'show options' wrap which is difficult to
23+
# read, store to a temp file
24+
rhosts_file = Rex::Quickfile.new("msf-db-rhosts-")
25+
mydatastore['RHOSTS'] = 'file:'+rhosts_file.path
26+
# create the output file and assign it to the RHOSTS variable
27+
rhosts_file.write(rhosts.join("\n")+"\n")
28+
rhosts_file.close
29+
else
30+
# For short lists, just set it directly
31+
mydatastore['RHOSTS'] = rhosts.join(" ")
32+
end
33+
34+
print_line "RHOSTS => #{mydatastore['RHOSTS']}"
35+
print_line
36+
end

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module CommandDispatcher
2020
class Core
2121

2222
include Msf::Ui::Console::CommandDispatcher
23+
require 'msf/core/set_rhosts'
2324

2425
# Session command options
2526
@@sessions_opts = Rex::Parser::Arguments.new(
@@ -74,7 +75,8 @@ class Core
7475
"-B" => [ true, "Show arg lines of output Before a match." ],
7576
"-s" => [ true, "Skip arg lines of output before attempting match."],
7677
"-k" => [ true, "Keep (include) arg lines at start of output." ],
77-
"-c" => [ false, "Only print a count of matching lines." ])
78+
"-c" => [ false, "Only print a count of matching lines." ],
79+
"-R" => [ false, "Set RHOSTS with the results, can only be used when command output has 'addresses' as the first column" ])
7880

7981
@@search_opts = Rex::Parser::Arguments.new(
8082
"-h" => [ false, "Help banner." ])
@@ -2486,6 +2488,11 @@ def cmd_grep(*args)
24862488
# skip arg number of lines at the top of the output, useful for avoiding undesirable matches
24872489
output_mods[:skip] = val.to_i
24882490
args.shift(2)
2491+
when "-R"
2492+
output_mods[:set_rhosts] = true
2493+
args.shift
2494+
output_mods[:keep] = 6 unless output_mods[:keep].to_i > 6 # we need the column headers
2495+
rhosts = []
24892496
end
24902497
end
24912498
# after deleting parsed options, the only args left should be the pattern, the cmd to run, and cmd args
@@ -2555,7 +2562,25 @@ def temp_output.write(msg = '')
25552562

25562563
# now control output based on remaining output_mods such as :count
25572564
return print_status(count.to_s) if output_mods[:count]
2558-
our_lines.each {|line| print line}
2565+
2566+
if output_mods[:set_rhosts]
2567+
# we don't use the db to confirm these hosts because we want to keep grep independent of db status so we
2568+
# require the first column to be the addresses otherwise there's no good way to parse the table.to_s output
2569+
col_names_row_index = nil
2570+
our_lines.each_with_index do |line,idx|
2571+
if line =~ /^address/ # this is assumed to be the line w/the column names
2572+
col_names_row_index = idx
2573+
break
2574+
end
2575+
end
2576+
rhosts_row_start = col_names_row_index + 1
2577+
rhosts_row_start += 1 if our_lines[rhosts_row_start] =~ /^-+/ # skip the "-----" separator if present
2578+
row_of_interest = our_lines.slice(rhosts_row_start..-1)
2579+
rhosts = row_of_interest.map {|row| row.split(/\s/).first}
2580+
set_rhosts_from_addrs(rhosts)
2581+
else
2582+
our_lines.each {|line| print line}
2583+
end
25592584
end
25602585

25612586
#

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

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module CommandDispatcher
1111
class Db
1212

1313
require 'tempfile'
14+
require 'msf/core/set_rhosts'
1415

1516
include Msf::Ui::Console::CommandDispatcher
1617

@@ -1476,7 +1477,7 @@ def cmd_db_rebuild_cache
14761477
print_error("The database is not connected")
14771478
return
14781479
end
1479-
1480+
14801481
print_status("Purging and rebuilding the module cache in the background...")
14811482
framework.threads.spawn("ModuleCacheRebuild", true) do
14821483
framework.db.purge_all_module_details
@@ -1491,44 +1492,6 @@ def cmd_db_rebuild_cache_help
14911492
print_line
14921493
end
14931494

1494-
#
1495-
# Set RHOSTS in the +active_module+'s (or global if none) datastore from an array of addresses
1496-
#
1497-
# This stores all the addresses to a temporary file and utilizes the
1498-
# <pre>file:/tmp/filename</pre> syntax to confer the addrs. +rhosts+
1499-
# should be an Array. NOTE: the temporary file is *not* deleted
1500-
# automatically.
1501-
#
1502-
def set_rhosts_from_addrs(rhosts)
1503-
if rhosts.empty?
1504-
print_status "The list is empty, cowardly refusing to set RHOSTS"
1505-
return
1506-
end
1507-
if active_module
1508-
mydatastore = active_module.datastore
1509-
else
1510-
# if there is no module in use set the list to the global variable
1511-
mydatastore = self.framework.datastore
1512-
end
1513-
1514-
if rhosts.length > 5
1515-
# Lots of hosts makes 'show options' wrap which is difficult to
1516-
# read, store to a temp file
1517-
rhosts_file = Rex::Quickfile.new("msf-db-rhosts-")
1518-
mydatastore['RHOSTS'] = 'file:'+rhosts_file.path
1519-
# create the output file and assign it to the RHOSTS variable
1520-
rhosts_file.write(rhosts.join("\n")+"\n")
1521-
rhosts_file.close
1522-
else
1523-
# For short lists, just set it directly
1524-
mydatastore['RHOSTS'] = rhosts.join(" ")
1525-
end
1526-
1527-
print_line "RHOSTS => #{mydatastore['RHOSTS']}"
1528-
print_line
1529-
end
1530-
1531-
15321495
def db_find_tools(tools)
15331496
found = true
15341497
missed = []

0 commit comments

Comments
 (0)