mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-01-08 14:36:22 +01:00
c74376fb69
This updates the packet header so that the encryption byte flag is now 32 bits. This also updates the powershell and python extensions so that both of the bindings work correctly as a result of the TLV packet header changes.
97 lines
3.1 KiB
C
Executable File
97 lines
3.1 KiB
C
Executable File
/*!
|
|
* @file python_meterpreter_binding.c
|
|
* @brief Definitions for functions that support meterpreter bindings.
|
|
*/
|
|
#include "../../common/common.h"
|
|
#include "python_main.h"
|
|
#include "Python.h"
|
|
|
|
static PLIST gBoundCommandList = NULL;
|
|
static PyObject* gMeterpreterModule = NULL;
|
|
static PyMethodDef* gMeterpreterMethods = NULL;
|
|
static PLIST gMeterpreterMethodDefs = NULL;
|
|
|
|
static PyObject* binding_invoke(PyObject* self, PyObject* args)
|
|
{
|
|
dprintf("[PYTHON] a function was invoked on: %s", self->ob_type->tp_name);
|
|
const char* packetBytes = NULL;
|
|
BOOL isLocal = FALSE;
|
|
Py_ssize_t packetLength = 0;
|
|
|
|
PyArg_ParseTuple(args, "is#", &isLocal, &packetBytes, &packetLength);
|
|
dprintf("[PYTHON] packet %p is %u bytes and is %s", packetBytes, packetLength, isLocal ? "local" : "not local");
|
|
|
|
Packet packet = { 0 };
|
|
packet.header = *(PacketHeader*)packetBytes;
|
|
packet.payload = (PUCHAR)(packetBytes + sizeof(PacketHeader));
|
|
packet.payloadLength = (ULONG)packetLength - sizeof(PacketHeader);
|
|
|
|
// If the functionality doesn't require interaction with MSF, then
|
|
// make the packet as local so that the packet receives the request
|
|
// and so that the packet doesn't get sent to Meterpreter
|
|
packet.local = isLocal;
|
|
|
|
command_handle(gRemote, &packet);
|
|
|
|
// really not sure how to deal with the non-local responses at this point.
|
|
if (packet.partner == NULL)
|
|
{
|
|
// "None"
|
|
return Py_BuildValue("");
|
|
}
|
|
|
|
PyObject* result = PyString_FromStringAndSize(packet.partner->payload, packet.partner->payloadLength);
|
|
packet_destroy(packet.partner);
|
|
return result;
|
|
}
|
|
|
|
VOID binding_insert_command(const char* commandName)
|
|
{
|
|
static PyMethodDef def;
|
|
dprintf("[PYTHON] inserting command %s", commandName);
|
|
def.ml_name = commandName;
|
|
def.ml_meth = binding_invoke;
|
|
def.ml_flags = METH_VARARGS;
|
|
def.ml_doc = NULL;
|
|
|
|
PyObject* fun = PyCFunction_New(&def, gMeterpreterModule);
|
|
PyModule_AddObject(gMeterpreterModule, commandName, fun);
|
|
}
|
|
|
|
VOID binding_startup()
|
|
{
|
|
if (gBoundCommandList == NULL)
|
|
{
|
|
gBoundCommandList = list_create();
|
|
}
|
|
}
|
|
|
|
VOID binding_add_command(const char* commandName)
|
|
{
|
|
dprintf("[PYTHON] Adding command %s", (char*)commandName);
|
|
|
|
// only add non-core commands
|
|
if (_strnicmp("core_", commandName, 5) != 0)
|
|
{
|
|
list_add(gBoundCommandList, (char*)commandName);
|
|
binding_insert_command(commandName);
|
|
}
|
|
}
|
|
|
|
VOID binding_init()
|
|
{
|
|
dprintf("[PYTHON] Initialising binding...");
|
|
gMeterpreterModule = Py_InitModule("meterpreter_bindings", NULL);
|
|
|
|
// we have a hard-coded core command binding for all core commands. This allows us to use
|
|
// the one function for all base core commands that aren't included as part of the "normal"
|
|
// mechanisms for extension loading. Without this, we'd have to manually wire in each of the
|
|
// base commands, which doesn't make sense. Instead we can match against core command names
|
|
// and funnel through this binding knowing that they'll be there regardless of the wiring.
|
|
binding_insert_command("meterpreter_core");
|
|
for (PNODE node = gBoundCommandList->start; node != NULL; node = node->next)
|
|
{
|
|
binding_insert_command((const char*)node->data);
|
|
}
|
|
}
|