mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-05-06 16:09:38 +02:00
168 lines
4.4 KiB
C
Executable File
168 lines
4.4 KiB
C
Executable File
/*!
|
|
* @file python_commands.c
|
|
* @brief Definitions for the python command bindings.
|
|
*/
|
|
#include "Python.h"
|
|
#include "python_main.h"
|
|
#include "python_commands.h"
|
|
|
|
static LIST* stderrBuffer = NULL;
|
|
static LIST* stdoutBuffer = NULL;
|
|
|
|
static PyObject* handle_write(LIST* target, PyObject* self, PyObject* args)
|
|
{
|
|
const char* written = NULL;
|
|
if (PyArg_ParseTuple(args, "s", &written))
|
|
{
|
|
dprintf("[PYTHON] something written to %p: %s", target, written);
|
|
list_add(target, strdup(written));
|
|
}
|
|
else
|
|
{
|
|
dprintf("[PYTHON] something written to %p (can't parse)", target);
|
|
}
|
|
return Py_BuildValue("");
|
|
}
|
|
|
|
static PyObject* handle_stderr(PyObject* self, PyObject* args)
|
|
{
|
|
return handle_write(stderrBuffer, self, args);
|
|
}
|
|
|
|
static PyObject* handle_stdout(PyObject* self, PyObject* args)
|
|
{
|
|
return handle_write(stdoutBuffer, self, args);
|
|
}
|
|
|
|
static PyMethodDef meterpreter_stdout_hooks[] =
|
|
{
|
|
{ "write", handle_stdout, METH_VARARGS, "Write something to stdout" },
|
|
{ NULL, NULL, 0, NULL }
|
|
};
|
|
|
|
static PyMethodDef meterpreter_stderr_hooks[] =
|
|
{
|
|
{ "write", handle_stderr, METH_VARARGS, "Write something to stderr" },
|
|
{ NULL, NULL, 0, NULL }
|
|
};
|
|
|
|
static VOID dump_to_packet_and_destroy(LIST* source, Packet* packet, UINT tlvType)
|
|
{
|
|
lock_acquire(source->lock);
|
|
|
|
PNODE current = source->start;
|
|
|
|
while (current != NULL)
|
|
{
|
|
packet_add_tlv_string(packet, tlvType, (LPCSTR)current->data);
|
|
current = current->next;
|
|
}
|
|
|
|
lock_release(source->lock);
|
|
list_destroy(source);
|
|
}
|
|
|
|
/*!
|
|
* @brief Hook into key bits of python (such as stdout/stderr)
|
|
*/
|
|
VOID initialize_hooks()
|
|
{
|
|
PyObject* stdoutModule = Py_InitModule("meterpreter_stdout", meterpreter_stdout_hooks);
|
|
|
|
if (stdoutModule != NULL && PySys_SetObject("stdout", stdoutModule) == 0)
|
|
{
|
|
dprintf("[PYTHON] Successfully set the stdout hook");
|
|
}
|
|
else
|
|
{
|
|
dprintf("[PYTHON] Failed to set the stdout hook");
|
|
}
|
|
|
|
PyObject* stderrModule = Py_InitModule("meterpreter_stderr", meterpreter_stderr_hooks);
|
|
if (stderrModule != NULL && PySys_SetObject("stderr", stderrModule) == 0)
|
|
{
|
|
dprintf("[PYTHON] Successfully set the stderr hook");
|
|
}
|
|
else
|
|
{
|
|
dprintf("[PYTHON] Failed to set the stderr hook");
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* @brief Reset/restart the interpreter.
|
|
* @param remote Pointer to the \c Remote making the request.
|
|
* @param packet Pointer to the request \c Packet.
|
|
* @returns Indication of success or failure.
|
|
*/
|
|
DWORD request_python_reset(Remote* remote, Packet* packet)
|
|
{
|
|
dprintf("[PYTHON] resetting the interpreter");
|
|
Py_Finalize();
|
|
Py_Initialize();
|
|
initialize_hooks();
|
|
packet_transmit_empty_response(remote, packet, ERROR_SUCCESS);
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
/*!
|
|
* @brief Execute a block of python given in a string and return the result/output.
|
|
* @param remote Pointer to the \c Remote making the request.
|
|
* @param packet Pointer to the request \c Packet.
|
|
* @returns Indication of success or failure.
|
|
*/
|
|
DWORD request_python_execute_string(Remote* remote, Packet* packet)
|
|
{
|
|
DWORD dwResult = ERROR_SUCCESS;
|
|
Packet* response = packet_create_response(packet);
|
|
CHAR* pythonCode = packet_get_tlv_value_string(packet, TLV_TYPE_EXTENSION_PYTHON_CODE);
|
|
|
|
if (pythonCode != NULL)
|
|
{
|
|
dprintf("[PYTHON] attempting to run string: %s", pythonCode);
|
|
|
|
stderrBuffer = list_create();
|
|
stdoutBuffer = list_create();
|
|
|
|
PyRun_SimpleString(pythonCode);
|
|
|
|
CHAR* resultVar = packet_get_tlv_value_string(packet, TLV_TYPE_EXTENSION_PYTHON_RESULT_VAR);
|
|
if (resultVar)
|
|
{
|
|
PyObject* mainModule = PyImport_AddModule("__main__");
|
|
if (mainModule != NULL)
|
|
{
|
|
PyObject* mainDict = PyModule_GetDict(mainModule);
|
|
if (mainDict != NULL)
|
|
{
|
|
PyObject* result = PyDict_GetItemString(mainDict, resultVar);
|
|
if (result != NULL)
|
|
{
|
|
if (PyString_Check(result))
|
|
{
|
|
// result is already a string
|
|
packet_add_tlv_string(response, TLV_TYPE_EXTENSION_PYTHON_RESULT, PyString_AsString(result));
|
|
}
|
|
else
|
|
{
|
|
PyObject* resultStr = PyObject_Str(result);
|
|
packet_add_tlv_string(response, TLV_TYPE_EXTENSION_PYTHON_RESULT, PyString_AsString(resultStr));
|
|
Py_DECREF(resultStr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dump_to_packet_and_destroy(stderrBuffer, response, TLV_TYPE_EXTENSION_PYTHON_STDERR);
|
|
dump_to_packet_and_destroy(stdoutBuffer, response, TLV_TYPE_EXTENSION_PYTHON_STDOUT);
|
|
|
|
stderrBuffer = NULL;
|
|
stdoutBuffer = NULL;
|
|
|
|
packet_transmit_response(dwResult, remote, response);
|
|
}
|
|
|
|
return dwResult;
|
|
} |