From 2802f17cd5d4540ac306f957f94c4e1cbceb53e5 Mon Sep 17 00:00:00 2001 From: Green-m Date: Mon, 25 Jun 2018 05:30:49 -0400 Subject: [PATCH] Add command persist to make job persistent after msf restart. --- lib/msf/ui/console/command_dispatcher/jobs.rb | 115 +++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/lib/msf/ui/console/command_dispatcher/jobs.rb b/lib/msf/ui/console/command_dispatcher/jobs.rb index 797e0b9192..4d588871e9 100644 --- a/lib/msf/ui/console/command_dispatcher/jobs.rb +++ b/lib/msf/ui/console/command_dispatcher/jobs.rb @@ -38,12 +38,20 @@ module Msf "-S" => [ true, "Row search filter." ], ) + @@persist_opts = Rex::Parser::Arguments.new( + "-h" => [ false, "Help banner." ], + "-C" => [ false, "Clean all persistent jobs." ], + "-a" => [ true, "Add a persistent job by job ID" ], + "-l" => [ false, "List all persistent jobs." ] + ) + def commands { "jobs" => "Displays and manages jobs", "rename_job" => "Rename a job", "kill" => "Kill a job", - "handler" => "Start a payload handler as job" + "handler" => "Start a payload handler as job", + "persist" => "Displays and manages persistent jobs" } end @@ -159,6 +167,7 @@ module Msf cmd_jobs_help return false end + end if dump_list @@ -354,6 +363,110 @@ module Msf } tab_complete_generic(fmt, str, words) end + + def cmd_persist_help + print_line "Usage: persist [options]" + print_line + print_line "Persist job manipulation and interaction." + print @@persist_opts.usage + end + + # + # Displays and manages persistent jobs for the framework. + # + + def cmd_persist(*args) + # Make the default behavior listing all jobs if there were no options + # or the only option is the verbose flag + args.unshift("-l") if args.empty? + + persist_file = Msf::Config.persist_file + verbose = false + dump_list = false + dump_info = false + job_id = nil + persistence = false + + # Parse the command options + @@persist_opts.parse(args) do |opt, _idx, val| + case opt + when "-l" + dump_list = true + # Cleaning all persistent jobs + when "-C" + print_line("Cleaning all persistent jobs...") + File.truncate(persist_file,0) + # Add persistent job + when "-a" + job_id = val + persistence = true + when "-h" + cmd_persist_help + return false + end + end + + if dump_list + persistent_jobs = File.open(persist_file,"r").readlines.map!(&:chomp) rescue nil + print_line("\nPersistent Jobs\n===============\n") + + unless persistent_jobs.blank? + persistent_jobs.map!{|job|JSON.parse(job)} + + persistent_jobs.each do |job| + print_line("#{job['mod_name']} - #{job['mod_options']['Payload']} - #{job['mod_options']["Options"]["lhost"]}:#{job['mod_options']["Options"]["LPORT"]}") + print_line + end + else + print_line("No persistent jobs.\n") + end + end + + if persistence + if job_id && framework.jobs.has_key?(job_id.to_s) + mod = framework.jobs[job_id.to_s].ctx[0].replicant + payload = framework.jobs[job_id.to_s].ctx[1].replicant + + payload_opts = { + 'Payload' => payload.refname, + 'Options' => payload.datastore, + #'LocalInput' => driver.input, + #'LocalOutput' => driver.output, + 'RunAsJob' => true + } + + mod_opts = { + 'mod_name' => mod.fullname, + 'mod_options' => payload_opts + } + + File.open(persist_file,"a+"){|file|file.puts(mod_opts.to_json)} + print_line("Added job #{job_id} as a persistent_job.") + else + print_line("Invalid Job ID") + end + #handler.exploit_simple(payload_opts) + end + end + + + # + # Tab completion for the persist command + # + # @param str [String] the string currently being typed before tab was hit + # @param words [Array] the previously completed words on the command line. words is always + # at least 1 when tab completion has reached this stage since the command itself has been completed + + def cmd_persist_tabs(_str, words) + return @@persist_opts.fmt.keys if words.length == 1 + + if words.length == 2 && (@@persist_opts.fmt[words[1]] || [false])[0] + return framework.jobs.keys + end + + [] + end + end end end