1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-04-12 04:12:05 +02:00
OJ 3f574e3521
Implement extendion IDs and refactor command enum
Enumeration of commands was a bit of a hack, and still resultsed in
strings (like "stdapi") to appear in binaries, and also meant that
extensions needed to identify themselves.

This code changes the way this works. Extensions no longer have a name.
Instead they have an internal ID tha maps to the command sets they
support. To enumerate extension commands, MSF will ask for a range of
commands, and if any command IDs fit within that range, they'll be
returned.

This moves us towards a nicer way of handling things across all the
meterpreters.
2020-05-01 15:36:07 +10:00

51 lines
2.0 KiB
C++
Executable File

/*!
* @file powershell_bindings.cpp
* @brief Wrapper functions for bridging native meterp calls to powershell
*/
extern "C" {
#include "common.h"
#include "common_metapi.h"
#include "powershell_bindings.h"
}
Remote* gRemote = NULL;
VOID MeterpreterInvoke(unsigned int isLocal, unsigned char* input, unsigned int inputLength, unsigned char** output, unsigned int* outputLength)
{
dprintf("[PSH BINDING] Input %p of %d bytes received", input, inputLength);
Packet packet = { 0 };
packet.header = *(PacketHeader*)input;
packet.header.length = ntohl(packet.header.length);
packet.payload = (PUCHAR)(input + sizeof(PacketHeader));
packet.payloadLength = (ULONG)inputLength - sizeof(PacketHeader);
packet.local = isLocal == 1;
dprintf("[PSH BINDING] Packet header length: %u", packet.header.length);
dprintf("[PSH BINDING] Packet header type: %u", packet.header.type);
dprintf("[PSH BINDING] Packet payload length: %u", packet.payloadLength);
dprintf("[PSH BINDING] Packet local flag: %u", isLocal);
dprintf("[PSH BINDING] Request ID: %s", met_api->packet.get_tlv_value_string(&packet, TLV_TYPE_REQUEST_ID));
dprintf("[PSH BINDING] Command ID: %u", met_api->packet.get_tlv_value_uint(&packet, TLV_TYPE_COMMAND_ID));
met_api->command.handle(gRemote, &packet);
if (packet.partner != NULL)
{
dprintf("[PSH BINDING] Response packet generated");
// This memory is deliberately left allocated, because the .NET side will clean it up
*output = (unsigned char*)LocalAlloc(LPTR, packet.partner->payloadLength);
*outputLength = packet.partner->payloadLength;
memcpy(*output, packet.partner->payload, packet.partner->payloadLength);
dprintf("[PSH BINDING] Partner packet copied");
met_api->packet.destroy(packet.partner);
dprintf("[PSH BINDING] Partner packet destroyed");
}
else
{
dprintf("[PSH BINDING] Response packet not generated");
*output = NULL;
*outputLength = 0;
}
dprintf("[PSH BINDING] MeterpreterInvoke done.");
}