Skip to content

Commit 15dc335

Browse files
committed
In pymeterpreter use a MeterpreterFile obj for Py v3
1 parent d8dcfd8 commit 15dc335

File tree

2 files changed

+33
-20
lines changed

2 files changed

+33
-20
lines changed

data/meterpreter/ext_server_stdapi.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ def get_stat_buffer(path):
508508
blocks = si.st_blocks
509509
st_buf = struct.pack('<IHHH', si.st_dev, min(0xffff, si.st_ino), si.st_mode, si.st_nlink)
510510
st_buf += struct.pack('<HHHI', si.st_uid, si.st_gid, 0, rdev)
511-
st_buf += struct.pack('<IIII', si.st_size, si.st_atime, si.st_mtime, si.st_ctime)
511+
st_buf += struct.pack('<IIII', si.st_size, long(si.st_atime), long(si.st_mtime), long(si.st_ctime))
512512
st_buf += struct.pack('<II', blksize, blocks)
513513
return st_buf
514514

@@ -603,7 +603,7 @@ def channel_open_stdapi_fs_file(request, response):
603603
else:
604604
fmode = 'rb'
605605
file_h = open(fpath, fmode)
606-
channel_id = meterpreter.add_channel(file_h)
606+
channel_id = meterpreter.add_channel(MeterpreterFile(file_h))
607607
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
608608
return ERROR_SUCCESS, response
609609

@@ -737,11 +737,12 @@ def stdapi_sys_process_getpid(request, response):
737737

738738
def stdapi_sys_process_get_processes_via_proc(request, response):
739739
for pid in os.listdir('/proc'):
740-
pgroup = ''
740+
pgroup = bytes()
741741
if not os.path.isdir(os.path.join('/proc', pid)) or not pid.isdigit():
742742
continue
743-
cmd = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read(512).replace('\x00', ' ')
744-
status_data = open(os.path.join('/proc', pid, 'status'), 'rb').read()
743+
cmdline_file = open(os.path.join('/proc', pid, 'cmdline'), 'rb')
744+
cmd = str(cmdline_file.read(512).replace(NULL_BYTE, bytes(' ', 'UTF-8')))
745+
status_data = str(open(os.path.join('/proc', pid, 'status'), 'rb').read())
745746
status_data = map(lambda x: x.split('\t',1), status_data.split('\n'))
746747
status = {}
747748
for k, v in filter(lambda x: len(x) == 2, status_data):
@@ -893,7 +894,8 @@ def stdapi_fs_delete_dir(request, response):
893894
@meterpreter.register_function
894895
def stdapi_fs_delete_file(request, response):
895896
file_path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
896-
os.unlink(file_path)
897+
if os.path.exists(file_path):
898+
os.unlink(file_path)
897899
return ERROR_SUCCESS, response
898900

899901
@meterpreter.register_function
@@ -955,7 +957,8 @@ def stdapi_fs_md5(request, response):
955957
@meterpreter.register_function
956958
def stdapi_fs_mkdir(request, response):
957959
dir_path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
958-
os.mkdir(dir_path)
960+
if not os.path.isdir(dir_path):
961+
os.mkdir(dir_path)
959962
return ERROR_SUCCESS, response
960963

961964
@meterpreter.register_function
@@ -1423,7 +1426,7 @@ def stdapi_registry_query_value(request, response):
14231426
if result == ERROR_SUCCESS:
14241427
response += tlv_pack(TLV_TYPE_VALUE_TYPE, value_type.value)
14251428
if value_type.value == REG_SZ:
1426-
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data) + '\x00')
1429+
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data) + NULL_BYTE)
14271430
elif value_type.value == REG_DWORD:
14281431
value = value_data[:4]
14291432
value.reverse()

data/meterpreter/meterpreter.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def packet_enum_tlvs(pkt, tlv_type = None):
146146
if (tlv_type == None) or ((tlv[1] & ~TLV_META_TYPE_COMPRESSED) == tlv_type):
147147
val = pkt[offset+8:(offset+8+(tlv[0] - 8))]
148148
if (tlv[1] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
149-
val = val.split(NULL_BYTE, 1)[0]
149+
val = str(val.split(NULL_BYTE, 1)[0])
150150
elif (tlv[1] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
151151
val = struct.unpack('>I', val)[0]
152152
elif (tlv[1] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
@@ -190,6 +190,15 @@ def tlv_pack(*args):
190190
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
191191
return data
192192

193+
#@export
194+
class MeterpreterFile(object):
195+
def __init__(self, file_obj):
196+
self.file_obj = file_obj
197+
198+
def __getattr__(self, name):
199+
return getattr(self.file_obj, name)
200+
export(MeterpreterFile)
201+
193202
#@export
194203
class MeterpreterSocket(object):
195204
def __init__(self, sock):
@@ -271,6 +280,7 @@ def register_function_windll(self, func):
271280
return func
272281

273282
def add_channel(self, channel):
283+
assert(isinstance(channel, (subprocess.Popen, MeterpreterFile, MeterpreterSocket)))
274284
idx = 0
275285
while idx in self.channels:
276286
idx += 1
@@ -392,10 +402,10 @@ def _core_channel_close(self, request, response):
392402
if channel_id not in self.channels:
393403
return ERROR_FAILURE, response
394404
channel = self.channels[channel_id]
395-
if isinstance(channel, file):
396-
channel.close()
397-
elif isinstance(channel, subprocess.Popen):
405+
if isinstance(channel, subprocess.Popen):
398406
channel.kill()
407+
elif isinstance(channel, MeterpreterFile):
408+
channel.close()
399409
elif isinstance(channel, MeterpreterSocket):
400410
channel.close()
401411
else:
@@ -411,7 +421,7 @@ def _core_channel_eof(self, request, response):
411421
return ERROR_FAILURE, response
412422
channel = self.channels[channel_id]
413423
result = False
414-
if isinstance(channel, file):
424+
if isinstance(channel, MeterpreterFile):
415425
result = channel.tell() >= os.fstat(channel.fileno()).st_size
416426
response += tlv_pack(TLV_TYPE_BOOL, result)
417427
return ERROR_SUCCESS, response
@@ -438,13 +448,13 @@ def _core_channel_read(self, request, response):
438448
return ERROR_FAILURE, response
439449
channel = self.channels[channel_id]
440450
data = ''
441-
if isinstance(channel, file):
442-
data = channel.read(length)
443-
elif isinstance(channel, STDProcess):
451+
if isinstance(channel, STDProcess):
444452
if channel.poll() != None:
445453
self.handle_dead_resource_channel(channel_id)
446454
if channel.stdout_reader.is_read_ready():
447455
data = channel.stdout_reader.read(length)
456+
elif isinstance(channel, MeterpreterFile):
457+
data = channel.read(length)
448458
elif isinstance(channel, MeterpreterSocket):
449459
data = channel.recv(length)
450460
else:
@@ -460,13 +470,13 @@ def _core_channel_write(self, request, response):
460470
return ERROR_FAILURE, response
461471
channel = self.channels[channel_id]
462472
l = len(channel_data)
463-
if isinstance(channel, file):
464-
channel.write(channel_data)
465-
elif isinstance(channel, subprocess.Popen):
473+
if isinstance(channel, subprocess.Popen):
466474
if channel.poll() != None:
467475
self.handle_dead_resource_channel(channel_id)
468476
return ERROR_FAILURE, response
469477
channel.stdin.write(channel_data)
478+
elif isinstance(channel, MeterpreterFile):
479+
channel.write(channel_data)
470480
elif isinstance(channel, MeterpreterSocket):
471481
try:
472482
l = channel.send(channel_data)
@@ -487,7 +497,7 @@ def create_response(self, request):
487497
reqid_tlv = packet_get_tlv(request, TLV_TYPE_REQUEST_ID)
488498
resp += tlv_pack(reqid_tlv)
489499

490-
handler_name = str(method_tlv['value'])
500+
handler_name = method_tlv['value']
491501
if handler_name in self.extension_functions:
492502
handler = self.extension_functions[handler_name]
493503
try:

0 commit comments

Comments
 (0)