class Rex::Post::Meterpreter::Extensions::Stdapi::Sys::Process
This class implements the Rex::Post::Process
interface.
Attributes
Public Class Methods
Returns the process identifier of the process supplied in key if it's valid.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 43 def Process.[](key) each_process { |p| if (p['name'].downcase == key.downcase) return p['pid'] end } return nil end
Low-level process open.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 81 def Process._open(pid, perms, inherit = false) request = Packet.create_request('stdapi_sys_process_attach') if (pid == nil) pid = 0 end # 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) # Transmit the request response = self.client.send_request(request) handle = response.get_tlv_value(TLV_TYPE_HANDLE) # If the handle is valid, allocate a process instance and return it if (handle != nil) return self.new(pid, handle) end return nil end
Closes the handle to the process that was opened.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 312 def self.close(client, handle) request = Packet.create_request('stdapi_sys_process_close') request.add_tlv(TLV_TYPE_HANDLE, handle) response = client.send_request(request, nil) handle = nil; return true end
Enumerates all of the elements in the array returned by get_processes.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 209 def Process.each_process(&block) self.get_processes.each(&block) end
Executes an application using the arguments provided
Hash arguments supported:
Hidden => true/false Channelized => true/false Suspended => true/false InMemory => true/false
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 115 def Process.execute(path, arguments = nil, opts = nil) request = Packet.create_request('stdapi_sys_process_execute') flags = 0 # 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 if (opts['UseThreadToken']) flags |= PROCESS_EXECUTE_FLAG_USE_THREAD_TOKEN end 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 inmem = opts['InMemory'] if inmem # add the file contents into the tlv f = ::File.new(path, 'rb') request.add_tlv(TLV_TYPE_VALUE_DATA, f.read(f.stat.size)) f.close # replace the path with the "dummy" path = inmem.kind_of?(String) ? inmem : 'cmd' end end request.add_tlv(TLV_TYPE_PROCESS_PATH, client.unicode_filter_decode( path )); # If process arguments were supplied if (arguments != nil) request.add_tlv(TLV_TYPE_PROCESS_ARGUMENTS, arguments); end request.add_tlv(TLV_TYPE_PROCESS_FLAGS, flags); response = client.send_request(request) # 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 # If we were creating a channel out of this if (channel_id != nil) channel = Rex::Post::Meterpreter::Channels::Pools::StreamPool.new(client, channel_id, "stdapi_process", CHANNEL_FLAG_SYNCHRONOUS) end # Return a process instance return self.new(pid, handle, channel) end
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 291 def self.finalize(client, handle) proc { self.close(client, handle) } end
Returns a ProcessList
of processes as Hash objects with keys for 'pid', 'ppid', 'name', 'path', 'user', 'session' and 'arch'.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 217 def Process.get_processes request = Packet.create_request('stdapi_sys_process_get_processes') processes = ProcessList.new response = client.send_request(request) response.each(TLV_TYPE_PROCESS_GROUP) { |p| arch = "" pa = p.get_tlv_value( TLV_TYPE_PROCESS_ARCH ) if( pa != nil ) if pa == 1 # PROCESS_ARCH_X86 arch = ARCH_X86 elsif pa == 2 # PROCESS_ARCH_X64 arch = ARCH_X86_64 end end processes << { 'pid' => p.get_tlv_value(TLV_TYPE_PID), 'ppid' => p.get_tlv_value(TLV_TYPE_PARENT_PID), '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) ), 'session' => p.get_tlv_value(TLV_TYPE_PROCESS_SESSION), 'user' => client.unicode_filter_encode( p.get_tlv_value(TLV_TYPE_USER_NAME) ), 'arch' => arch } } return processes end
Gets the process id that the remote side is executing under.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 198 def Process.getpid request = Packet.create_request('stdapi_sys_process_getpid') response = client.send_request(request) return response.get_tlv_value(TLV_TYPE_PID) end
Kills one or more processes.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 183 def Process.kill(*args) request = Packet.create_request('stdapi_sys_process_kill') args.each { |id| request.add_tlv(TLV_TYPE_PID, id) } client.send_request(request) return true end
Initializes the process instance and its aliases.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 266 def initialize(pid, handle, channel = nil) self.client = self.class.client self.handle = handle self.channel = channel # 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 initialize_aliases( { 'image' => Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Image.new(self), 'io' => Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::IO.new(self), 'memory' => Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Memory.new(self), 'thread' => Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Thread.new(self), }) # Ensure the remote object is closed when all references are removed ObjectSpace.define_finalizer(self, self.class.finalize(client, handle)) end
Attachs to the supplied process with a given set of permissions.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 56 def Process.open(pid = nil, perms = nil) real_perms = 0 if (perms == nil) perms = PROCESS_ALL end if (perms & PROCESS_READ) real_perms |= PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION end if (perms & PROCESS_WRITE) real_perms |= PROCESS_SET_SESSIONID | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION end if (perms & PROCESS_EXECUTE) real_perms |= PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_CREATE_PROCESS | PROCESS_SUSPEND_RESUME end return _open(pid, real_perms) end
An alias for get_processes.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 253 def Process.processes self.get_processes end
Public Instance Methods
Instance method
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 323 def close(handle = self.handle) unless self.pid.nil? ObjectSpace.undefine_finalizer(self) self.class.close(self.client, handle) self.pid = nil end end
Returns the executable name of the process.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 298 def name return get_info()['name'] end
Returns the path to the process' executable.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 305 def path return get_info()['path'] end
Block until this process terminates on the remote side. By default we choose not to allow a packet responce timeout to occur as we may be waiting indefinatly for the process to terminate.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 336 def wait( timeout = -1 ) request = Packet.create_request('stdapi_sys_process_wait') request.add_tlv(TLV_TYPE_HANDLE, self.handle) response = self.client.send_request(request, timeout) self.handle = nil return true end
Protected Instance Methods
Gathers information about the process and returns a hash.
# File lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb, line 355 def get_info request = Packet.create_request('stdapi_sys_process_get_info') info = {} request.add_tlv(TLV_TYPE_HANDLE, handle) # Send the request response = client.send_request(request) # Populate the hash 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) ) return info end