From f9bf4e3100c405da71cb19ecbe24105c081494d6 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Thu, 19 Mar 2015 17:23:00 -0400 Subject: [PATCH] Fix pymet for unicode files and directories Closes #4958 --- data/meterpreter/ext_server_stdapi.py | 26 ++++++++++++++++++-------- data/meterpreter/meterpreter.py | 6 +++++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/data/meterpreter/ext_server_stdapi.py b/data/meterpreter/ext_server_stdapi.py index 31811139a4..176146d3dc 100644 --- a/data/meterpreter/ext_server_stdapi.py +++ b/data/meterpreter/ext_server_stdapi.py @@ -63,9 +63,11 @@ else: if isinstance(__builtins__, dict): is_str = lambda obj: issubclass(obj.__class__, __builtins__['str']) str = lambda x: __builtins__['str'](x, 'UTF-8') + unicode = __builtins__['str'] else: is_str = lambda obj: issubclass(obj.__class__, __builtins__.str) str = lambda x: __builtins__.str(x, 'UTF-8') + unicode = __builtins__.str is_bytes = lambda obj: issubclass(obj.__class__, bytes) NULL_BYTE = bytes('\x00', 'UTF-8') long = int @@ -923,18 +925,24 @@ def stdapi_sys_process_get_processes(request, response): @meterpreter.register_function def stdapi_fs_chdir(request, response): wd = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value'] + if sys.version_info[0] < 3: + wd = wd.decode('UTF-8') os.chdir(wd) return ERROR_SUCCESS, response @meterpreter.register_function def stdapi_fs_delete(request, response): file_path = packet_get_tlv(request, TLV_TYPE_FILE_NAME)['value'] + if sys.version_info[0] < 3: + file_path = file_path.decode('UTF-8') os.unlink(file_path) return ERROR_SUCCESS, response @meterpreter.register_function def stdapi_fs_delete_dir(request, response): dir_path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value'] + if sys.version_info[0] < 3: + dir_path = dir_path.decode('UTF-8') if os.path.islink(dir_path): del_func = os.unlink else: @@ -945,6 +953,8 @@ def stdapi_fs_delete_dir(request, response): @meterpreter.register_function def stdapi_fs_delete_file(request, response): file_path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] + if sys.version_info[0] < 3: + file_path = file_path.decode('UTF-8') os.unlink(file_path) return ERROR_SUCCESS, response @@ -983,13 +993,13 @@ def stdapi_fs_getwd(request, response): def stdapi_fs_ls(request, response): path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value'] path = os.path.abspath(path) - contents = os.listdir(path) - contents.sort() - for x in contents: - y = os.path.join(path, x) - response += tlv_pack(TLV_TYPE_FILE_NAME, x) - response += tlv_pack(TLV_TYPE_FILE_PATH, y) - response += tlv_pack(TLV_TYPE_STAT_BUF, get_stat_buffer(y)) + dir_contents = os.listdir(unicode(path)) + dir_contents.sort() + for file_name in dir_contents: + file_path = os.path.join(path, file_name) + response += tlv_pack(TLV_TYPE_FILE_NAME, file_name) + response += tlv_pack(TLV_TYPE_FILE_PATH, file_path) + response += tlv_pack(TLV_TYPE_STAT_BUF, get_stat_buffer(file_path)) return ERROR_SUCCESS, response @meterpreter.register_function @@ -1027,7 +1037,7 @@ def stdapi_fs_search(request, response): file_tlv += tlv_pack(TLV_TYPE_FILE_SIZE, os.stat(os.path.join(root, f)).st_size) response += tlv_pack(TLV_TYPE_SEARCH_RESULTS, file_tlv) else: - for f in filter(lambda f: fnmatch.fnmatch(f, glob), os.listdir(search_root)): + for f in filter(lambda f: fnmatch.fnmatch(f, glob), os.listdir(unicode(search_root))): file_tlv = '' file_tlv += tlv_pack(TLV_TYPE_FILE_PATH, search_root) file_tlv += tlv_pack(TLV_TYPE_FILE_NAME, f) diff --git a/data/meterpreter/meterpreter.py b/data/meterpreter/meterpreter.py index 3c0832dbe1..d6e19d7424 100644 --- a/data/meterpreter/meterpreter.py +++ b/data/meterpreter/meterpreter.py @@ -45,9 +45,11 @@ else: if isinstance(__builtins__, dict): is_str = lambda obj: issubclass(obj.__class__, __builtins__['str']) str = lambda x: __builtins__['str'](x, 'UTF-8') + unicode = __builtins__['str'] else: is_str = lambda obj: issubclass(obj.__class__, __builtins__.str) str = lambda x: __builtins__.str(x, 'UTF-8') + unicode = __builtins__.str is_bytes = lambda obj: issubclass(obj.__class__, bytes) NULL_BYTE = bytes('\x00', 'UTF-8') long = int @@ -262,7 +264,9 @@ def tlv_pack(*args): data = struct.pack('>II', 9, tlv['type']) + bytes(chr(int(bool(tlv['value']))), 'UTF-8') else: value = tlv['value'] - if not is_bytes(value): + if sys.version_info[0] < 3 and isinstance(value, unicode): + value = value.encode('UTF-8') + elif not is_bytes(value): value = bytes(value, 'UTF-8') if (tlv['type'] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING: data = struct.pack('>II', 8 + len(value) + 1, tlv['type']) + value + NULL_BYTE