Skip to content

Commit 2008dcb

Browse files
David MaloneyDavid Maloney
authored andcommitted
create jobs command dispatcher
split the jobs related commands into their own command dispatcher to start cleaning up the 'core' dispatcher
1 parent d08aff2 commit 2008dcb

File tree

4 files changed

+264
-212
lines changed

4 files changed

+264
-212
lines changed

lib/msf/ui/console/command_dispatcher.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,36 @@ def log_error(err)
7474
dlog("Call stack:\n#{$@.join("\n")}", 'core', LEV_1)
7575
end
7676

77+
#
78+
# Generate an array of job or session IDs from a given range String.
79+
# Always returns an Array.
80+
#
81+
# @param id_list [String] Range or list description such as 1-5 or 1,3,5 etc
82+
# @return [Array<String>] Representing the range
83+
def build_range_array(id_list)
84+
item_list = []
85+
unless id_list.blank?
86+
temp_list = id_list.split(',')
87+
temp_list.each do |ele|
88+
return if ele.count('-') > 1
89+
return if ele.first == '-' || ele[-1] == '-'
90+
return if ele.first == '.' || ele[-1] == '.'
91+
92+
if ele.include? '-'
93+
temp_array = (ele.split("-").inject { |s, e| s.to_i..e.to_i }).to_a
94+
item_list.concat(temp_array)
95+
elsif ele.include? '..'
96+
temp_array = (ele.split("..").inject { |s, e| s.to_i..e.to_i }).to_a
97+
item_list.concat(temp_array)
98+
else
99+
item_list.push(ele.to_i)
100+
end
101+
end
102+
end
103+
104+
item_list.uniq.sort
105+
end
106+
77107
#
78108
# The driver that this command dispatcher is associated with.
79109
#

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

Lines changed: 1 addition & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
require 'msf/ui/console/command_dispatcher/payload'
1717
require 'msf/ui/console/command_dispatcher/auxiliary'
1818
require 'msf/ui/console/command_dispatcher/post'
19+
require 'msf/ui/console/command_dispatcher/jobs'
1920
require 'msf/util/document_generator'
2021

2122
module Msf
@@ -49,14 +50,6 @@ class Core
4950
"-t" => [ true, "Set a response timeout (default: 15)" ],
5051
"-x" => [ false, "Show extended information in the session table" ])
5152

52-
@@jobs_opts = Rex::Parser::Arguments.new(
53-
"-h" => [ false, "Help banner." ],
54-
"-k" => [ true, "Terminate jobs by job ID and/or range." ],
55-
"-K" => [ false, "Terminate all running jobs." ],
56-
"-i" => [ true, "Lists detailed information about a running job."],
57-
"-l" => [ false, "List all running jobs." ],
58-
"-v" => [ false, "Print more detailed info. Use with -i and -l" ])
59-
6053
@@threads_opts = Rex::Parser::Arguments.new(
6154
"-h" => [ false, "Help banner." ],
6255
"-k" => [ true, "Terminate the specified thread ID." ],
@@ -121,9 +114,6 @@ def commands
121114
"info" => "Displays information about one or more modules",
122115
"options" => "Displays global options or for one or more modules",
123116
"irb" => "Drop into irb scripting mode",
124-
"jobs" => "Displays and manages jobs",
125-
"rename_job" => "Rename a job",
126-
"kill" => "Kill a job",
127117
"load" => "Load a framework plugin",
128118
"loadpath" => "Searches for and loads modules from a path",
129119
"popm" => "Pops the latest module off the stack and makes it active",
@@ -922,179 +912,6 @@ def cmd_irb(*args)
922912
end
923913
end
924914

925-
def cmd_rename_job_help
926-
print_line "Usage: rename_job [ID] [Name]"
927-
print_line
928-
print_line "Example: rename_job 0 \"meterpreter HTTPS special\""
929-
print_line
930-
print_line "Rename a job that's currently active."
931-
print_line "You may use the jobs command to see what jobs are available."
932-
print_line
933-
end
934-
935-
def cmd_rename_job(*args)
936-
if args.include?('-h') || args.length != 2 || args[0] !~ /^\d+$/
937-
cmd_rename_job_help
938-
return false
939-
end
940-
941-
job_id = args[0].to_s
942-
job_name = args[1].to_s
943-
944-
unless framework.jobs[job_id]
945-
print_error("Job #{job_id} does not exist.")
946-
return false
947-
end
948-
949-
# This is not respecting the Protected access control, but this seems to be the only way
950-
# to rename a job. If you know a more appropriate way, patches accepted.
951-
framework.jobs[job_id].send(:name=, job_name)
952-
print_status("Job #{job_id} updated")
953-
954-
true
955-
end
956-
957-
#
958-
# Tab completion for the rename_job command
959-
#
960-
# @param str [String] the string currently being typed before tab was hit
961-
# @param words [Array<String>] the previously completed words on the command line. words is always
962-
# at least 1 when tab completion has reached this stage since the command itself has been completed
963-
964-
def cmd_rename_job_tabs(str, words)
965-
return [] if words.length > 1
966-
framework.jobs.keys
967-
end
968-
969-
def cmd_jobs_help
970-
print_line "Usage: jobs [options]"
971-
print_line
972-
print_line "Active job manipulation and interaction."
973-
print @@jobs_opts.usage()
974-
end
975-
976-
#
977-
# Displays and manages running jobs for the active instance of the
978-
# framework.
979-
#
980-
def cmd_jobs(*args)
981-
# Make the default behavior listing all jobs if there were no options
982-
# or the only option is the verbose flag
983-
args.unshift("-l") if args.length == 0 || args == ["-v"]
984-
985-
verbose = false
986-
dump_list = false
987-
dump_info = false
988-
job_id = nil
989-
990-
# Parse the command options
991-
@@jobs_opts.parse(args) do |opt, idx, val|
992-
case opt
993-
when "-v"
994-
verbose = true
995-
when "-l"
996-
dump_list = true
997-
# Terminate the supplied job ID(s)
998-
when "-k"
999-
job_list = build_range_array(val)
1000-
if job_list.blank?
1001-
print_error("Please specify valid job identifier(s)")
1002-
return false
1003-
end
1004-
print_status("Stopping the following job(s): #{job_list.join(', ')}")
1005-
job_list.map(&:to_s).each do |job|
1006-
if framework.jobs.has_key?(job)
1007-
print_status("Stopping job #{job}")
1008-
framework.jobs.stop_job(job)
1009-
else
1010-
print_error("Invalid job identifier: #{job}")
1011-
end
1012-
end
1013-
when "-K"
1014-
print_line("Stopping all jobs...")
1015-
framework.jobs.each_key do |i|
1016-
framework.jobs.stop_job(i)
1017-
end
1018-
when "-i"
1019-
# Defer printing anything until the end of option parsing
1020-
# so we can check for the verbose flag.
1021-
dump_info = true
1022-
job_id = val
1023-
when "-h"
1024-
cmd_jobs_help
1025-
return false
1026-
end
1027-
end
1028-
1029-
if dump_list
1030-
print("\n#{Serializer::ReadableText.dump_jobs(framework, verbose)}\n")
1031-
end
1032-
if dump_info
1033-
if job_id && framework.jobs[job_id.to_s]
1034-
job = framework.jobs[job_id.to_s]
1035-
mod = job.ctx[0]
1036-
1037-
output = '\n'
1038-
output += "Name: #{mod.name}"
1039-
output += ", started at #{job.start_time}" if job.start_time
1040-
print_line(output)
1041-
1042-
show_options(mod) if mod.options.has_options?
1043-
1044-
if verbose
1045-
mod_opt = Serializer::ReadableText.dump_advanced_options(mod,' ')
1046-
if mod_opt && mod_opt.length > 0
1047-
print_line("\nModule advanced options:\n\n#{mod_opt}\n")
1048-
end
1049-
end
1050-
else
1051-
print_line("Invalid Job ID")
1052-
end
1053-
end
1054-
end
1055-
1056-
#
1057-
# Tab completion for the jobs command
1058-
#
1059-
# @param str [String] the string currently being typed before tab was hit
1060-
# @param words [Array<String>] the previously completed words on the command line. words is always
1061-
# at least 1 when tab completion has reached this stage since the command itself has been completed
1062-
1063-
def cmd_jobs_tabs(str, words)
1064-
if words.length == 1
1065-
return @@jobs_opts.fmt.keys
1066-
end
1067-
1068-
if words.length == 2 and (@@jobs_opts.fmt[words[1]] || [false])[0]
1069-
return framework.jobs.keys
1070-
end
1071-
1072-
[]
1073-
end
1074-
1075-
def cmd_kill_help
1076-
print_line "Usage: kill <job1> [job2 ...]"
1077-
print_line
1078-
print_line "Equivalent to 'jobs -k job1 -k job2 ...'"
1079-
print @@jobs_opts.usage()
1080-
end
1081-
1082-
def cmd_kill(*args)
1083-
cmd_jobs("-k", *args)
1084-
end
1085-
1086-
#
1087-
# Tab completion for the kill command
1088-
#
1089-
# @param str [String] the string currently being typed before tab was hit
1090-
# @param words [Array<String>] the previously completed words on the command line. words is always
1091-
# at least 1 when tab completion has reached this stage since the command itself has been completed
1092-
1093-
def cmd_kill_tabs(str, words)
1094-
return [] if words.length > 1
1095-
framework.jobs.keys
1096-
end
1097-
1098915
def cmd_threads_help
1099916
print_line "Usage: threads [options]"
1100917
print_line
@@ -3606,35 +3423,7 @@ def retrieve_grep_lines(all_lines,line_num, before = nil, after = nil)
36063423
all_lines.slice(start..finish)
36073424
end
36083425

3609-
#
3610-
# Generate an array of job or session IDs from a given range String.
3611-
# Always returns an Array.
3612-
#
3613-
# @param id_list [String] Range or list description such as 1-5 or 1,3,5 etc
3614-
# @return [Array<String>] Representing the range
3615-
def build_range_array(id_list)
3616-
item_list = []
3617-
unless id_list.blank?
3618-
temp_list = id_list.split(',')
3619-
temp_list.each do |ele|
3620-
return if ele.count('-') > 1
3621-
return if ele.first == '-' || ele[-1] == '-'
3622-
return if ele.first == '.' || ele[-1] == '.'
36233426

3624-
if ele.include? '-'
3625-
temp_array = (ele.split("-").inject { |s, e| s.to_i..e.to_i }).to_a
3626-
item_list.concat(temp_array)
3627-
elsif ele.include? '..'
3628-
temp_array = (ele.split("..").inject { |s, e| s.to_i..e.to_i }).to_a
3629-
item_list.concat(temp_array)
3630-
else
3631-
item_list.push(ele.to_i)
3632-
end
3633-
end
3634-
end
3635-
3636-
item_list.uniq.sort
3637-
end
36383427

36393428
end
36403429

0 commit comments

Comments
 (0)