2012-06-29 00:18:28 -05:00
# -*- coding: binary -*-
2005-04-15 06:23:59 +00:00
2005-07-09 21:18:49 +00:00
require 'rex/post/process'
require 'rex/post/meterpreter/packet'
require 'rex/post/meterpreter/client'
require 'rex/post/meterpreter/channels/pools/stream_pool'
require 'rex/post/meterpreter/extensions/stdapi/stdapi'
2005-04-15 06:23:59 +00:00
2005-07-09 21:18:49 +00:00
require 'rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image'
require 'rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io'
require 'rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory'
require 'rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread'
2005-04-15 06:23:59 +00:00
module Rex
module Post
module Meterpreter
module Extensions
module Stdapi
module Sys
##
#
# This class implements the Rex::Post::Process interface.
#
##
class Process < Rex :: Post :: Process
include Rex :: Post :: Meterpreter :: ObjectAliasesContainer
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
##
#
# Class methods
#
##
2013-08-30 16:28:33 -05:00
2010-01-02 00:35:10 +00:00
class << self
2005-04-15 06:23:59 +00:00
attr_accessor :client
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
2005-04-15 07:03:33 +00:00
# Returns the process identifier of the process supplied in key if it's
2005-11-15 05:22:13 +00:00
# valid.
#
2005-04-15 07:03:33 +00:00
def Process . [] ( key )
2020-03-12 09:59:08 +00:00
return if key . nil?
2020-03-10 12:54:00 +00:00
2005-04-15 07:03:33 +00:00
each_process { | p |
if ( p [ 'name' ] . downcase == key . downcase )
return p [ 'pid' ]
end
}
2013-08-30 16:28:33 -05:00
2005-04-15 07:03:33 +00:00
return nil
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
2024-01-06 15:54:49 -05:00
# Attaches to the supplied process with a given set of permissions.
2005-11-15 05:22:13 +00:00
#
2005-04-16 07:29:06 +00:00
def Process . open ( pid = nil , perms = nil )
2005-04-15 06:23:59 +00:00
real_perms = 0
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
if ( perms == nil )
perms = PROCESS_ALL
end
2013-08-30 16:28:33 -05:00
2022-06-30 13:27:51 -05:00
if ( perms & PROCESS_READ ) > 0
2005-04-15 06:23:59 +00:00
real_perms |= PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION
end
2013-08-30 16:28:33 -05:00
2022-06-30 13:27:51 -05:00
if ( perms & PROCESS_WRITE ) > 0
2005-04-15 06:23:59 +00:00
real_perms |= PROCESS_SET_SESSIONID | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION
end
2013-08-30 16:28:33 -05:00
2022-06-30 13:27:51 -05:00
if ( perms & PROCESS_EXECUTE ) > 0
2005-04-15 06:23:59 +00:00
real_perms |= PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_CREATE_PROCESS | PROCESS_SUSPEND_RESUME
end
2013-08-30 16:28:33 -05:00
2010-01-02 00:35:10 +00:00
return _open ( pid , real_perms )
2005-04-15 06:23:59 +00:00
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
# Low-level process open.
#
2005-04-16 07:29:06 +00:00
def Process . _open ( pid , perms , inherit = false )
2020-05-04 13:32:08 +10:00
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_ATTACH )
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
if ( pid == nil )
pid = 0
end
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
# Populate the request
request . add_tlv ( TLV_TYPE_PID , pid )
request . add_tlv ( TLV_TYPE_PROCESS_PERMS , perms )
request . add_tlv ( TLV_TYPE_INHERIT , inherit )
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
# Transmit the request
response = self . client . send_request ( request )
handle = response . get_tlv_value ( TLV_TYPE_HANDLE )
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
# If the handle is valid, allocate a process instance and return it
if ( handle != nil )
2005-04-16 07:29:06 +00:00
return self . new ( pid , handle )
2005-04-15 06:23:59 +00:00
end
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
return nil
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
2005-04-15 06:23:59 +00:00
# Executes an application using the arguments provided
2024-04-10 16:18:52 +10:00
# @param path [String] Path on the remote system to the executable to run
2024-10-23 00:35:47 +01:00
# @param arguments [String,Array<String>] Arguments to the process. When passed as a String (rather than an array of Strings),
2024-04-10 16:18:52 +10:00
# this is treated as a string containing all arguments.
# @param opts [Hash] Optional settings to parameterise the process launch
# @option Hidden [Boolean] Is the process launched without creating a visible window
# @option Channelized [Boolean] The process is launched with pipes connected to a channel, e.g. for sending input/receiving output
# @option Suspended [Boolean] Start the process suspended
# @option UseThreadToken [Boolean] Use the thread token (as opposed to the process token) to launch the process
# @option Desktop [Boolean] Run on meterpreter's current desktopt
# @option Session [Integer] Execute process in a given session as the session user
# @option Subshell [Boolean] Execute process in a subshell
# @option Pty [Boolean] Execute process in a pty (if available)
# @option ParentId [Integer] Spoof the parent PID (if possible)
# @option InMemory [Boolean,String] Execute from memory (`path` is treated as a local file to upload, and the actual path passed
# to meterpreter is this parameter's value, if provided as a String)
# @option :legacy_args [String] When arguments is an array, this is the command to execute if the receiving Meterpreter does not support arguments as an array
2005-04-16 20:37:27 +00:00
#
2024-04-18 20:42:01 +10:00
def Process . execute ( path , arguments = '' , opts = nil )
2020-05-04 13:32:08 +10:00
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_EXECUTE )
2005-04-16 20:37:27 +00:00
flags = 0
2013-08-30 16:28:33 -05:00
2005-04-16 20:37:27 +00:00
# If we were supplied optional arguments...
if ( opts != nil )
if ( opts [ 'Hidden' ] )
flags |= PROCESS_EXECUTE_FLAG_HIDDEN
end
if ( opts [ 'Channelized' ] )
flags |= PROCESS_EXECUTE_FLAG_CHANNELIZED
end
if ( opts [ 'Suspended' ] )
flags |= PROCESS_EXECUTE_FLAG_SUSPENDED
end
2008-04-28 16:57:49 +00:00
if ( opts [ 'UseThreadToken' ] )
flags |= PROCESS_EXECUTE_FLAG_USE_THREAD_TOKEN
end
2010-03-11 17:11:27 +00:00
if ( opts [ 'Desktop' ] )
flags |= PROCESS_EXECUTE_FLAG_DESKTOP
end
if ( opts [ 'Session' ] )
flags |= PROCESS_EXECUTE_FLAG_SESSION
request . add_tlv ( TLV_TYPE_PROCESS_SESSION , opts [ 'Session' ] )
end
2019-04-18 15:30:26 +08:00
if ( opts [ 'Subshell' ] )
flags |= PROCESS_EXECUTE_FLAG_SUBSHELL
end
2021-09-21 11:36:50 +01:00
if ( opts [ 'Pty' ] )
flags |= PROCESS_EXECUTE_FLAG_PTY
end
2019-12-17 01:04:55 +01:00
if ( opts [ 'ParentPid' ] )
request . add_tlv ( TLV_TYPE_PARENT_PID , opts [ 'ParentPid' ] ) ;
request . add_tlv ( TLV_TYPE_PROCESS_PERMS , PROCESS_ALL_ACCESS )
request . add_tlv ( TLV_TYPE_INHERIT , false )
end
2005-07-22 03:38:37 +00:00
inmem = opts [ 'InMemory' ]
if inmem
2013-08-30 16:28:33 -05:00
2005-07-22 03:38:37 +00:00
# add the file contents into the tlv
2009-03-23 21:04:39 +00:00
f = :: File . new ( path , 'rb' )
request . add_tlv ( TLV_TYPE_VALUE_DATA , f . read ( f . stat . size ) )
2005-07-22 03:38:37 +00:00
f . close
2013-08-30 16:28:33 -05:00
2005-07-22 03:38:37 +00:00
# replace the path with the "dummy"
path = inmem . kind_of? ( String ) ? inmem : 'cmd'
end
end
2013-08-30 16:28:33 -05:00
2024-04-09 13:06:30 +10:00
# Add arguments
2005-07-22 03:38:37 +00:00
# If process arguments were supplied
2024-04-18 20:42:01 +10:00
if arguments . kind_of? ( Array )
2024-10-23 00:35:47 +01:00
request . add_tlv ( TLV_TYPE_PROCESS_UNESCAPED_PATH , client . unicode_filter_decode ( path ) )
2024-04-18 20:42:01 +10:00
# This flag is needed to disambiguate how to handle escaping special characters in the path when no arguments are provided
flags |= PROCESS_EXECUTE_FLAG_ARG_ARRAY
arguments . each do | arg |
request . add_tlv ( TLV_TYPE_PROCESS_ARGUMENT , arg ) ;
end
if opts [ :legacy_path ]
request . add_tlv ( TLV_TYPE_PROCESS_PATH , opts [ :legacy_path ] )
end
if opts [ :legacy_args ]
request . add_tlv ( TLV_TYPE_PROCESS_ARGUMENTS , opts [ :legacy_args ] )
2024-04-09 13:06:30 +10:00
end
2024-10-23 00:35:47 +01:00
elsif arguments . nil? || arguments . kind_of? ( String )
request . add_tlv ( TLV_TYPE_PROCESS_PATH , client . unicode_filter_decode ( path ) )
2024-04-18 20:42:01 +10:00
request . add_tlv ( TLV_TYPE_PROCESS_ARGUMENTS , arguments )
else
raise ArgumentError . new ( 'Unknown type for arguments' )
2005-04-16 20:37:27 +00:00
end
2013-08-30 16:28:33 -05:00
2005-04-16 20:37:27 +00:00
request . add_tlv ( TLV_TYPE_PROCESS_FLAGS , flags ) ;
2013-08-30 16:28:33 -05:00
2005-04-16 20:37:27 +00:00
response = client . send_request ( request )
2013-08-30 16:28:33 -05:00
2005-04-16 20:37:27 +00:00
# Get the response parameters
pid = response . get_tlv_value ( TLV_TYPE_PID )
handle = response . get_tlv_value ( TLV_TYPE_PROCESS_HANDLE )
channel_id = response . get_tlv_value ( TLV_TYPE_CHANNEL_ID )
channel = nil
2013-08-30 16:28:33 -05:00
2005-04-16 20:37:27 +00:00
# If we were creating a channel out of this
if ( channel_id != nil )
2010-01-02 00:35:10 +00:00
channel = Rex :: Post :: Meterpreter :: Channels :: Pools :: StreamPool . new ( client ,
2020-03-12 15:45:31 -04:00
channel_id , " stdapi_process " , CHANNEL_FLAG_SYNCHRONOUS , response )
2005-04-16 20:37:27 +00:00
end
2013-08-30 16:28:33 -05:00
2009-06-17 01:34:33 +00:00
# Return a process instance
2005-04-16 20:37:27 +00:00
return self . new ( pid , handle , channel )
2010-03-11 17:11:27 +00:00
end
2013-08-30 16:28:33 -05:00
2021-05-04 20:48:58 +01:00
#
# Execute an application and capture the output
#
2024-04-18 20:42:01 +10:00
def Process . capture_output ( path , arguments = '' , opts = nil , time_out = 15 )
2021-05-04 20:48:58 +01:00
start = Time . now . to_i
process = execute ( path , arguments , opts )
data = " "
# Wait up to time_out seconds for the first bytes to arrive
while ( d = process . channel . read )
data << d
if d == " "
if Time . now . to_i - start < time_out
sleep 0 . 1
else
break
end
end
end
data . chomp! if data
begin
process . channel . close
rescue IOError = > e
# Channel was already closed, but we got the cmd output, so let's soldier on.
end
process . close
return data
end
2005-11-15 05:22:13 +00:00
#
# Kills one or more processes.
#
2005-04-18 00:10:38 +00:00
def Process . kill ( * args )
2020-05-04 13:32:08 +10:00
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_KILL )
2013-08-30 16:28:33 -05:00
2005-04-18 00:10:38 +00:00
args . each { | id |
request . add_tlv ( TLV_TYPE_PID , id )
}
2013-08-30 16:28:33 -05:00
2005-04-18 00:10:38 +00:00
client . send_request ( request )
2013-08-30 16:28:33 -05:00
2005-04-18 00:10:38 +00:00
return true
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
# Gets the process id that the remote side is executing under.
#
2005-04-15 06:23:59 +00:00
def Process . getpid
2020-05-04 13:32:08 +10:00
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_GETPID )
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
response = client . send_request ( request )
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
return response . get_tlv_value ( TLV_TYPE_PID )
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
# Enumerates all of the elements in the array returned by get_processes.
#
2005-04-15 07:03:33 +00:00
def Process . each_process ( & block )
self . get_processes . each ( & block )
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
2012-05-16 17:22:55 -06:00
# Returns a ProcessList of processes as Hash objects with keys for 'pid',
# 'ppid', 'name', 'path', 'user', 'session' and 'arch'.
2005-11-15 05:22:13 +00:00
#
2005-04-15 07:03:33 +00:00
def Process . get_processes
2020-05-04 13:32:08 +10:00
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_GET_PROCESSES )
2012-05-16 17:22:55 -06:00
processes = ProcessList . new
2013-08-30 16:28:33 -05:00
2005-04-15 07:03:33 +00:00
response = client . send_request ( request )
2013-08-30 16:28:33 -05:00
2005-04-15 07:03:33 +00:00
response . each ( TLV_TYPE_PROCESS_GROUP ) { | p |
2010-01-19 10:47:01 +00:00
arch = " "
2013-08-30 16:28:33 -05:00
2016-07-24 22:11:54 -05:00
pa = p . get_tlv_value ( TLV_TYPE_PROCESS_ARCH )
if ! pa . nil?
2010-01-25 10:49:51 +00:00
if pa == 1 # PROCESS_ARCH_X86
2010-01-19 10:47:01 +00:00
arch = ARCH_X86
2010-01-25 10:49:51 +00:00
elsif pa == 2 # PROCESS_ARCH_X64
2016-10-28 07:16:05 +10:00
arch = ARCH_X64
2010-01-19 10:47:01 +00:00
end
2016-07-24 22:11:54 -05:00
else
arch = p . get_tlv_value ( TLV_TYPE_PROCESS_ARCH_NAME )
2010-01-19 10:47:01 +00:00
end
2013-08-30 16:28:33 -05:00
2010-01-19 10:47:01 +00:00
processes <<
2005-04-15 07:03:33 +00:00
{
2010-01-19 10:47:01 +00:00
'pid' = > p . get_tlv_value ( TLV_TYPE_PID ) ,
2012-05-16 17:22:55 -06:00
'ppid' = > p . get_tlv_value ( TLV_TYPE_PARENT_PID ) ,
2011-07-21 15:26:15 +00:00
'name' = > client . unicode_filter_encode ( p . get_tlv_value ( TLV_TYPE_PROCESS_NAME ) ) ,
'path' = > client . unicode_filter_encode ( p . get_tlv_value ( TLV_TYPE_PROCESS_PATH ) ) ,
2010-03-11 17:11:27 +00:00
'session' = > p . get_tlv_value ( TLV_TYPE_PROCESS_SESSION ) ,
2011-07-21 15:26:15 +00:00
'user' = > client . unicode_filter_encode ( p . get_tlv_value ( TLV_TYPE_USER_NAME ) ) ,
2010-01-19 10:47:01 +00:00
'arch' = > arch
2005-04-15 07:03:33 +00:00
}
}
2013-08-30 16:28:33 -05:00
2005-04-15 07:03:33 +00:00
return processes
end
2013-08-30 16:28:33 -05:00
2005-12-13 05:59:59 +00:00
#
# An alias for get_processes.
#
def Process . processes
self . get_processes
end
2013-08-30 16:28:33 -05:00
2024-01-24 19:53:30 +00:00
#
# Search memory for supplied regexes and return matches
#
def Process . memory_search ( pid : 0 , needles : [ '' ] , min_match_length : 5 , max_match_length : 127 )
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_MEMORY_SEARCH )
request . add_tlv ( TLV_TYPE_PID , pid )
needles . each { | needle | request . add_tlv ( TLV_TYPE_MEMORY_SEARCH_NEEDLE , needle ) }
request . add_tlv ( TLV_TYPE_MEMORY_SEARCH_MATCH_LEN , max_match_length )
request . add_tlv ( TLV_TYPE_UINT , min_match_length )
self . client . send_request ( request )
end
2005-04-15 06:23:59 +00:00
##
#
# Instance methods
#
##
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
# Initializes the process instance and its aliases.
#
2005-04-16 20:37:27 +00:00
def initialize ( pid , handle , channel = nil )
self . client = self . class . client
self . handle = handle
self . channel = channel
2013-08-30 16:28:33 -05:00
2005-04-16 07:29:06 +00:00
# If the process identifier is zero, then we must lookup the current
# process identifier
if ( pid == 0 )
self . pid = client . sys . process . getpid
else
self . pid = pid
end
2013-08-30 16:28:33 -05:00
2005-04-15 06:23:59 +00:00
initialize_aliases (
{
2005-04-15 07:53:20 +00:00
'image' = > Rex :: Post :: Meterpreter :: Extensions :: Stdapi :: Sys :: ProcessSubsystem :: Image . new ( self ) ,
2005-04-16 20:37:27 +00:00
'io' = > Rex :: Post :: Meterpreter :: Extensions :: Stdapi :: Sys :: ProcessSubsystem :: IO . new ( self ) ,
2005-04-15 06:23:59 +00:00
'memory' = > Rex :: Post :: Meterpreter :: Extensions :: Stdapi :: Sys :: ProcessSubsystem :: Memory . new ( self ) ,
2005-04-16 07:29:06 +00:00
'thread' = > Rex :: Post :: Meterpreter :: Extensions :: Stdapi :: Sys :: ProcessSubsystem :: Thread . new ( self ) ,
2005-04-15 06:23:59 +00:00
} )
2013-08-30 16:28:33 -05:00
2016-03-04 12:08:19 -06:00
# Ensure the remote object is closed when all references are removed
ObjectSpace . define_finalizer ( self , self . class . finalize ( client , handle ) )
2005-04-15 06:23:59 +00:00
end
2013-08-30 16:28:33 -05:00
2016-03-04 12:08:19 -06:00
def self . finalize ( client , handle )
2023-02-07 16:43:18 +00:00
proc do
2023-05-05 13:50:38 +01:00
deferred_close_proc = proc do
begin
self . close ( client , handle )
rescue = > e
elog ( " finalize method for Process failed " , error : e )
end
2023-02-07 16:43:18 +00:00
end
2023-05-05 13:50:38 +01:00
# Schedule the finalizing logic out-of-band; as this logic might be called in the context of a Signal.trap, which can't synchronize mutexes
client . framework . sessions . schedule ( deferred_close_proc )
2023-02-07 16:43:18 +00:00
end
2010-10-16 19:39:11 +00:00
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
# Returns the executable name of the process.
#
2005-04-16 07:29:06 +00:00
def name
return get_info ( ) [ 'name' ]
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
# Returns the path to the process' executable.
#
2005-04-16 07:29:06 +00:00
def path
return get_info ( ) [ 'path' ]
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
#
# Closes the handle to the process that was opened.
#
2010-10-21 17:10:46 +00:00
def self . close ( client , handle )
2020-05-04 13:32:08 +10:00
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_CLOSE )
2005-04-15 07:03:33 +00:00
request . add_tlv ( TLV_TYPE_HANDLE , handle )
2020-05-04 13:32:08 +10:00
client . send_request ( request , nil )
2023-05-05 13:50:38 +01:00
handle = nil
2005-04-15 07:03:33 +00:00
return true
2010-03-11 17:11:27 +00:00
end
2013-08-30 16:28:33 -05:00
2010-10-16 19:39:11 +00:00
#
# Instance method
#
2016-03-04 12:08:19 -06:00
def close ( handle = self . handle )
unless self . pid . nil?
ObjectSpace . undefine_finalizer ( self )
self . class . close ( self . client , handle )
self . pid = nil
end
2010-10-16 19:39:11 +00:00
end
2013-08-30 16:28:33 -05:00
2010-03-11 17:11:27 +00:00
#
2010-10-16 19:39:11 +00:00
# Block until this process terminates on the remote side.
2024-01-06 15:54:49 -05:00
# By default we choose not to allow a packet response timeout to
2010-03-11 17:11:27 +00:00
# occur as we may be waiting indefinatly for the process to terminate.
#
def wait ( timeout = - 1 )
2020-05-04 13:32:08 +10:00
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_WAIT )
2013-08-30 16:28:33 -05:00
2010-03-11 17:11:27 +00:00
request . add_tlv ( TLV_TYPE_HANDLE , self . handle )
2013-08-30 16:28:33 -05:00
2020-05-04 13:32:08 +10:00
self . client . send_request ( request , timeout )
2013-08-30 16:28:33 -05:00
2010-03-11 17:11:27 +00:00
self . handle = nil
2013-08-30 16:28:33 -05:00
2010-03-11 17:11:27 +00:00
return true
end
2013-08-30 16:28:33 -05:00
2005-11-15 05:22:13 +00:00
attr_reader :client , :handle , :channel , :pid # :nodoc:
2005-04-15 06:23:59 +00:00
protected
2005-11-15 05:22:13 +00:00
attr_writer :client , :handle , :channel , :pid # :nodoc:
2005-04-16 07:29:06 +00:00
2005-11-15 05:22:13 +00:00
#
# Gathers information about the process and returns a hash.
#
2005-04-16 07:29:06 +00:00
def get_info
2020-05-04 13:32:08 +10:00
request = Packet . create_request ( COMMAND_ID_STDAPI_SYS_PROCESS_GET_INFO )
2005-04-16 07:29:06 +00:00
info = { }
request . add_tlv ( TLV_TYPE_HANDLE , handle )
# Send the request
response = client . send_request ( request )
# Populate the hash
2011-07-21 15:26:15 +00:00
info [ 'name' ] = client . unicode_filter_encode ( response . get_tlv_value ( TLV_TYPE_PROCESS_NAME ) )
info [ 'path' ] = client . unicode_filter_encode ( response . get_tlv_value ( TLV_TYPE_PROCESS_PATH ) )
2005-04-16 07:29:06 +00:00
return info
2010-03-11 17:11:27 +00:00
end
2005-04-15 06:23:59 +00:00
end
2012-05-16 17:22:55 -06:00
#
# Simple wrapper class for storing processes
#
class ProcessList < Array
#
2016-08-10 13:30:09 -05:00
# Create a Rex::Text::Table out of the processes stored in this list
2012-05-16 17:22:55 -06:00
#
2016-08-10 13:30:09 -05:00
# +opts+ is passed on to Rex::Text::Table.new, mostly unmolested
2012-05-16 17:22:55 -06:00
#
# Note that this output is affected by Rex::Post::Meterpreter::Client#unicode_filter_encode
#
def to_table ( opts = { } )
if empty?
2016-08-10 13:30:09 -05:00
return Rex :: Text :: Table . new ( opts )
2012-05-16 17:22:55 -06:00
end
2013-08-30 16:28:33 -05:00
2017-06-22 21:43:11 -05:00
column_headers = [ " PID " , " PPID " , " Name " , " Arch " , " Session " , " User " , " Path " ]
column_headers . delete_if do | h |
none? { | process | process . has_key? ( h . downcase ) } ||
all? { | process | process [ h . downcase ] . nil? }
2017-06-12 01:20:59 -04:00
end
2013-08-30 16:28:33 -05:00
2012-05-16 17:22:55 -06:00
opts = {
2015-07-25 17:31:56 -05:00
'Header' = > 'Process List' ,
'Indent' = > 1 ,
2017-06-22 21:43:11 -05:00
'Columns' = > column_headers
2012-05-16 17:22:55 -06:00
} . merge ( opts )
2013-08-30 16:28:33 -05:00
2016-08-10 13:30:09 -05:00
tbl = Rex :: Text :: Table . new ( opts )
2017-06-22 21:43:11 -05:00
each do | process |
tbl << column_headers . map do | header |
col = header . downcase
next unless process . keys . any? { | process_header | process_header == col }
2015-07-25 17:31:56 -05:00
val = process [ col ]
if col == 'session'
val == 0xFFFFFFFF ? '' : val . to_s
else
val
end
2017-06-22 21:43:11 -05:00
end
end
2013-08-30 16:28:33 -05:00
2012-05-16 17:22:55 -06:00
tbl
end
end
2009-03-23 21:04:39 +00:00
end ; end ; end ; end ; end ; end