add pkill command, rework to share filtering logic with ps

bug/bundler_fix
Brent Cook 2017-03-16 03:45:15 -05:00
parent a1be63e449
commit c9a85f58c0
1 changed files with 131 additions and 75 deletions

View File

@ -63,12 +63,13 @@ class Console::CommandDispatcher::Stdapi::Sys
# Options for the 'ps' command.
#
@@ps_opts = Rex::Parser::Arguments.new(
"-S" => [ true, "String to search for (converts to regex)" ],
"-h" => [ false, "Help menu." ],
"-A" => [ true, "Filters processes on architecture" ],
"-s" => [ false, "Show only SYSTEM processes" ],
"-c" => [ false, "Show only child processes of the current shell" ],
"-U" => [ true, "Filters processes on the user using the supplied RegEx"])
"-S" => [ true, "Filter on process name" ],
"-U" => [ true, "Filter on user name" ],
"-A" => [ true, "Filter on architecture" ],
"-x" => [ false, "Filter for exact matches rather than regex" ],
"-s" => [ false, "Filter only SYSTEM processes" ],
"-c" => [ false, "Filter only child processes of the current shell" ],
"-h" => [ false, "Help menu." ])
#
# Options for the 'suspend' command.
@ -92,6 +93,7 @@ class Console::CommandDispatcher::Stdapi::Sys
"getsid" => "Get the SID of the user that the server is running as",
"getenv" => "Get one or more environment variable values",
"kill" => "Terminate a process",
"pkill" => "Terminate a process by name",
"ps" => "List running processes",
"reboot" => "Reboots the remote computer",
"reg" => "Modify and interact with the remote registry",
@ -113,6 +115,7 @@ class Console::CommandDispatcher::Stdapi::Sys
"getsid" => [ "stdapi_sys_config_getsid" ],
"getenv" => [ "stdapi_sys_config_getenv" ],
"kill" => [ "stdapi_sys_process_kill" ],
"pkill" => [ "stdapi_sys_process_kill" ],
"ps" => [ "stdapi_sys_process_get_processes" ],
"reboot" => [ "stdapi_sys_power_exitwindows" ],
"reg" => [
@ -367,12 +370,37 @@ class Console::CommandDispatcher::Stdapi::Sys
end
#
# help for the kill command
# Kills one or more processes by name.
#
def cmd_kill_help
print_line("Usage: kill [pid1 [pid2 [pid3 ...]]] [-s]")
print_line("Terminate one or more processes.")
print_line(" -s : Kills the pid associated with the current session.")
def cmd_pkill(*args)
if args.include?('-h')
cmd_pkill_help
return true
end
all_processes = client.sys.process.get_processes
processes = match_processes(all_processes, args)
if processes.length == 0
print_line("No matching processes were found.")
return true
end
if processes.length == all_processes.length && !args.include?('-f')
print_error("All processes will be killed, use '-f' to force.")
return true
end
pids = processes.collect { |p| p['pid'] }
print_line("Killing: #{pids.join(', ')}")
client.sys.process.kill(*(pids.map { |x| x }))
true
end
def cmd_pkill_help
print_line("Usage: pkill [ options ] pattern")
print_line("Terminate one or more processes by name.")
print_line @@ps_opts.usage
end
#
@ -418,7 +446,87 @@ class Console::CommandDispatcher::Stdapi::Sys
valid_pids << pid
end
end
return valid_pids
valid_pids
end
def match_processes(processes, args)
search_proc = nil
search_user = nil
exact_match = false
# Parse opts
@@ps_opts.parse(args) do |opt, idx, val|
case opt
when '-S', nil
if val.nil? || val.empty?
print_error "Enter a process name"
processes = []
else
search_proc = val
end
when "-U"
if val.nil? || val.empty?
print_line "Enter a process user"
processes = []
else
search_user = val
end
when '-x'
exact_match = true
when "-A"
if val.nil? || val.empty?
print_error "Enter an architecture"
processes = []
else
print_line "Filtering on arch '#{val}"
processes = processes.select do |p|
p['arch'] == val
end
end
when "-s"
print_line "Filtering on SYSTEM processes..."
processes = processes.select do |p|
["NT AUTHORITY\\SYSTEM", "root"].include? p['user']
end
when "-c"
print_line "Filtering on child processes of the current shell..."
current_shell_pid = client.sys.process.getpid
processes = processes.select do |p|
p['ppid'] == current_shell_pid
end
end
end
unless search_proc.nil?
print_line "Filtering on '#{search_proc}'"
if exact_match
processes = processes.select do |p|
p['name'] == search_proc
end
else
match = /#{search_proc}/
processes = processes.select do |p|
p['name'] =~ match
end
end
end
unless search_user.nil?
print_line "Filtering on user '#{search_user}'"
if exact_match
processes = processes.select do |p|
p['user'] == search_user
end
else
match = /#{search_user}/
processes = processes.select do |p|
p['user'] =~ match
end
end
end
Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new(processes)
end
#
@ -430,80 +538,28 @@ class Console::CommandDispatcher::Stdapi::Sys
return true
end
# Init vars
processes = client.sys.process.get_processes
search_term = nil
all_processes = client.sys.process.get_processes
processes = match_processes(all_processes, args)
# Parse opts
@@ps_opts.parse(args) { |opt, idx, val|
case opt
when '-S'
search_term = val
if search_term.nil?
print_error("Enter a search term")
return true
end
when "-A"
print_line "Filtering on arch..."
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
processes.each do |proc|
next if proc['arch'].nil? or proc['arch'].empty?
if val.nil? or val.empty?
return false
end
searched_procs << proc if proc["arch"] == val
end
processes = searched_procs
when "-s"
print_line "Filtering on SYSTEM processes..."
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
processes.each do |proc|
searched_procs << proc if proc["user"] == "NT AUTHORITY\\SYSTEM"
end
processes = searched_procs
when "-c"
print_line "Filtering on child processes of the current shell..."
current_shell_pid = client.sys.process.getpid
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
processes.each do |proc|
searched_procs << proc if proc['ppid'] == current_shell_pid
end
processes = searched_procs
when "-U"
print_line "Filtering on user name..."
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
processes.each do |proc|
if val.nil? or val.empty?
print_line "You must supply a search term!"
return false
end
searched_procs << proc if proc["user"].match(/#{val}/)
end
processes = searched_procs
end
}
if (processes.length == 0)
print_line("No running processes were found.")
else
tbl = processes.to_table('SearchTerm' => search_term)
print_line
print_line(tbl.to_s)
if processes.length == 0
print_line("No matching processes were found.")
return true
end
return true
tbl = processes.to_table
print_line
print_line(tbl.to_s)
true
end
def cmd_ps_help
print_line "Usage: ps [ options ]"
print_line "Usage: ps [ options ] pattern"
print_line
print_line "Use the command with no arguments to see all running processes."
print_line "The following options can be used to filter those results:"
print_line @@ps_opts.usage
end
#
# Reboots the remote computer.
#