1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-11-20 14:39:22 +01:00

Add fix up tracking the process handle

This allows the process handle to be closed when the process was not
started by the Meterpreter instance.
This commit is contained in:
Spencer McIntyre 2023-03-02 15:54:37 -05:00
parent 5f79b77c3d
commit e01dbdbb5d
2 changed files with 29 additions and 25 deletions

View File

@ -1353,6 +1353,8 @@ def stdapi_sys_process_attach(request, response):
handle = OpenProcess(permissions, inherit, pid)
if not handle:
return error_result_windows(), response
meterpreter.processes[handle] = None
debug_print('[*] added process id: ' + str(pid) + ', handle: ' + str(handle))
response += tlv_pack(TLV_TYPE_HANDLE, handle)
return ERROR_SUCCESS, response

View File

@ -1259,6 +1259,21 @@ class PythonMeterpreter(object):
self.next_channel_id += 1
return idx
def close_channel(self, channel_id):
if channel_id not in self.channels:
return False
channel = self.channels[channel_id]
try:
channel.close()
except Exception:
debug_traceback('[-] failed to close channel id: ' + str(channel_id))
return False
del self.channels[channel_id]
if channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
debug_print('[*] closed and removed channel id: ' + str(channel_id))
return True
def add_process(self, process):
if has_windll:
PROCESS_ALL_ACCESS = 0x1fffff
@ -1274,37 +1289,24 @@ class PythonMeterpreter(object):
return handle
def close_process(self, proc_h_id):
proc_h = self.processes.pop(proc_h_id, None)
if not proc_h:
if proc_h_id not in self.processes:
return False
for channel_id, channel in self.channels.items():
if not isinstance(channel, MeterpreterProcess):
continue
if not channel.proc_h is proc_h:
continue
self.close_channel(channel_id)
break
proc_h = self.processes.pop(proc_h_id)
if proc_h:
# proc_h is only set when we started the process via execute and not when we attached to it
for channel_id, channel in self.channels.items():
if not isinstance(channel, MeterpreterProcess):
continue
if not channel.proc_h is proc_h:
continue
self.close_channel(channel_id)
break
if has_windll:
CloseHandle = ctypes.windll.kernel32.CloseHandle
CloseHandle.argtypes = [ctypes.c_void_p]
CloseHandle.restype = ctypes.c_long
CloseHandle(proc_h_id)
debug_print('[*] closed and removed process id: ' + str(proc_h.pid) + ', handle: ' + str(proc_h_id))
return True
def close_channel(self, channel_id):
if channel_id not in self.channels:
return False
channel = self.channels[channel_id]
try:
channel.close()
except Exception:
debug_traceback('[-] failed to close channel id: ' + str(channel_id))
return False
del self.channels[channel_id]
if channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
debug_print('[*] closed and removed channel id: ' + str(channel_id))
debug_print('[*] closed and removed process handle: ' + str(proc_h_id))
return True
def get_packet(self):