mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-01-20 20:37:27 +01:00
Add extension names, enuemrators, etc
This commit contains a bunch of code tidying (formatting, spaces, naming, etc) as well as new exports for each of the modules so that the extension can be identified. The plan is for the loader to know which modules are loaded so that when stageless meterpreter fires up MSF can query the existing extensions and load the appropriate functionality on the client side.
This commit is contained in:
parent
9c7f320301
commit
0393927159
@ -50,31 +50,31 @@ DWORD THREADCALL command_process_thread( THREAD * thread );
|
||||
Command baseCommands[] =
|
||||
{
|
||||
// Console commands
|
||||
{ "core_console_write",
|
||||
{ remote_request_core_console_write, NULL, { TLV_META_TYPE_STRING }, 1 | ARGUMENT_FLAG_REPEAT },
|
||||
{ remote_response_core_console_write, NULL, EMPTY_TLV },
|
||||
{ "core_console_write",
|
||||
{ remote_request_core_console_write, NULL, { TLV_META_TYPE_STRING }, 1 | ARGUMENT_FLAG_REPEAT },
|
||||
{ remote_response_core_console_write, NULL, EMPTY_TLV },
|
||||
},
|
||||
|
||||
// Native Channel commands
|
||||
// this overloads the "core_channel_open" in the base command list
|
||||
COMMAND_REQ_REP( "core_channel_open", remote_request_core_channel_open, remote_response_core_channel_open ),
|
||||
COMMAND_REQ( "core_channel_write", remote_request_core_channel_write ),
|
||||
COMMAND_REQ_REP( "core_channel_close", remote_request_core_channel_close, remote_response_core_channel_close ),
|
||||
COMMAND_REQ_REP("core_channel_open", remote_request_core_channel_open, remote_response_core_channel_open),
|
||||
COMMAND_REQ("core_channel_write", remote_request_core_channel_write),
|
||||
COMMAND_REQ_REP("core_channel_close", remote_request_core_channel_close, remote_response_core_channel_close),
|
||||
|
||||
// Buffered/Pool channel commands
|
||||
COMMAND_REQ( "core_channel_read", remote_request_core_channel_read ),
|
||||
COMMAND_REQ("core_channel_read", remote_request_core_channel_read),
|
||||
// Pool channel commands
|
||||
COMMAND_REQ( "core_channel_seek", remote_request_core_channel_seek ),
|
||||
COMMAND_REQ( "core_channel_eof", remote_request_core_channel_eof ),
|
||||
COMMAND_REQ( "core_channel_tell", remote_request_core_channel_tell ),
|
||||
COMMAND_REQ("core_channel_seek", remote_request_core_channel_seek),
|
||||
COMMAND_REQ("core_channel_eof", remote_request_core_channel_eof),
|
||||
COMMAND_REQ("core_channel_tell", remote_request_core_channel_tell),
|
||||
// Soon to be deprecated
|
||||
COMMAND_REQ( "core_channel_interact", remote_request_core_channel_interact ),
|
||||
COMMAND_REQ("core_channel_interact", remote_request_core_channel_interact),
|
||||
// Crypto
|
||||
COMMAND_REQ( "core_crypto_negotiate", remote_request_core_crypto_negotiate ),
|
||||
COMMAND_REQ("core_crypto_negotiate", remote_request_core_crypto_negotiate),
|
||||
// Migration
|
||||
COMMAND_INLINE_REQ( "core_migrate", remote_request_core_migrate ),
|
||||
COMMAND_INLINE_REQ("core_migrate", remote_request_core_migrate),
|
||||
// Shutdown
|
||||
COMMAND_INLINE_REQ( "core_shutdown", remote_request_core_shutdown ),
|
||||
COMMAND_INLINE_REQ("core_shutdown", remote_request_core_shutdown),
|
||||
// Terminator
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
@ -83,7 +83,7 @@ Command baseCommands[] =
|
||||
* @brief Dynamically registered command extensions.
|
||||
* @details A linked list of commands registered on the fly by reflectively-loaded extensions.
|
||||
*/
|
||||
Command *extensionCommands = NULL;
|
||||
Command* extensionCommands = NULL;
|
||||
|
||||
/*!
|
||||
* @brief Register a full list of commands with meterpreter.
|
||||
|
@ -168,7 +168,7 @@ void real_dprintf(char *filename, int line, const char *function, char *format,
|
||||
#include <wininet.h>
|
||||
|
||||
/*! @brief When defined, debug output is enabled on Windows builds. */
|
||||
#define DEBUGTRACE 1
|
||||
//#define DEBUGTRACE 1
|
||||
|
||||
#ifdef DEBUGTRACE
|
||||
#define dprintf(...) real_dprintf(__VA_ARGS__)
|
||||
|
@ -13,23 +13,24 @@
|
||||
* @returns A new instance of a linked list.
|
||||
* @retval NULL Indicates a memory allocation failure.
|
||||
*/
|
||||
LIST * list_create(VOID)
|
||||
PLIST list_create(VOID)
|
||||
{
|
||||
LIST * list = (LIST*)malloc(sizeof(LIST));
|
||||
if (list != NULL)
|
||||
{
|
||||
list->start = NULL;
|
||||
list->end = NULL;
|
||||
list->count = 0;
|
||||
list->lock = lock_create();
|
||||
PLIST pList = (PLIST)malloc(sizeof(LIST));
|
||||
|
||||
if (list->lock == NULL)
|
||||
if (pList != NULL)
|
||||
{
|
||||
pList->start = NULL;
|
||||
pList->end = NULL;
|
||||
pList->count = 0;
|
||||
pList->lock = lock_create();
|
||||
|
||||
if (pList->lock == NULL)
|
||||
{
|
||||
list_destroy(list);
|
||||
list_destroy(pList);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
return pList;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -38,16 +39,16 @@ LIST * list_create(VOID)
|
||||
* linked list. This is the responsibility of the caller to destroy.
|
||||
* @param list The \c LIST instance to destroy.
|
||||
*/
|
||||
VOID list_destroy(LIST * list)
|
||||
VOID list_destroy(PLIST pList)
|
||||
{
|
||||
NODE * current_node;
|
||||
NODE * next_node;
|
||||
PNODE current_node;
|
||||
PNODE next_node;
|
||||
|
||||
if (list != NULL)
|
||||
if (pList != NULL)
|
||||
{
|
||||
lock_acquire(list->lock);
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
current_node = list->start;
|
||||
current_node = pList->start;
|
||||
|
||||
while (current_node != NULL)
|
||||
{
|
||||
@ -62,34 +63,34 @@ VOID list_destroy(LIST * list)
|
||||
current_node = next_node;
|
||||
}
|
||||
|
||||
list->count = 0;
|
||||
pList->count = 0;
|
||||
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
|
||||
lock_destroy(list->lock);
|
||||
lock_destroy(pList->lock);
|
||||
|
||||
free(list);
|
||||
free(pList);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the number of items in the list.
|
||||
* @param list The \c LIST to get a count of.
|
||||
* @param pList The \c LIST to get a count of.
|
||||
* @returns The number of elements in the list.
|
||||
* @remark If using this coung value to itterate through the list with `list_get`, acquire
|
||||
* the lists lock before the `list_count/list_get` block and release it afterwards.
|
||||
*/
|
||||
DWORD list_count(LIST * list)
|
||||
DWORD list_count(PLIST pList)
|
||||
{
|
||||
DWORD count = 0;
|
||||
|
||||
if (list != NULL)
|
||||
if (pList != NULL)
|
||||
{
|
||||
lock_acquire(list->lock);
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
count = list->count;
|
||||
count = pList->count;
|
||||
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
}
|
||||
|
||||
return count;
|
||||
@ -97,29 +98,29 @@ DWORD list_count(LIST * list)
|
||||
|
||||
/*!
|
||||
* @brief Get the data value held in the list and a specified index.
|
||||
* @param list Pointer to the \c LIST to get the element from.
|
||||
* @param pList Pointer to the \c LIST to get the element from.
|
||||
* @param index Index of the element to get;
|
||||
* @returns Pointer to the item in the list.
|
||||
* @retval NULL Indicates the element doesn't exist in the list.
|
||||
* @remark This will perform a linear search from the beginning of the list.
|
||||
*/
|
||||
LPVOID list_get(LIST * list, DWORD index)
|
||||
LPVOID list_get(PLIST pList, DWORD index)
|
||||
{
|
||||
LPVOID data = NULL;
|
||||
NODE * current_node = NULL;
|
||||
PNODE current_node = NULL;
|
||||
|
||||
if (list == NULL)
|
||||
if (pList == NULL)
|
||||
return NULL;
|
||||
|
||||
lock_acquire(list->lock);
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
if (list->count <= index)
|
||||
if (pList->count <= index)
|
||||
{
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
current_node = list->start;
|
||||
current_node = pList->start;
|
||||
|
||||
while (current_node != NULL)
|
||||
{
|
||||
@ -138,93 +139,93 @@ LPVOID list_get(LIST * list, DWORD index)
|
||||
data = current_node->data;
|
||||
}
|
||||
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Add a data item onto the end of the list.
|
||||
* @param list Pointer to the \c LIST to add the item to.
|
||||
* @param pList Pointer to the \c LIST to add the item to.
|
||||
* @param data The data that is to be added to the list.
|
||||
* @returns Indication of success or failure.
|
||||
* @sa list_push
|
||||
*/
|
||||
BOOL list_add(LIST * list, LPVOID data)
|
||||
BOOL list_add(PLIST pList, LPVOID data)
|
||||
{
|
||||
return list_push(list, data);
|
||||
return list_push(pList, data);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Internal function to remove a node from a list.
|
||||
* @param list Pointer to the \c LIST containing \c node.
|
||||
* @param node Pointer to the \c NOTE to remove.
|
||||
* @param pList Pointer to the \c LIST containing \c node.
|
||||
* @param pNode Pointer to the \c NOTE to remove.
|
||||
* @returns Indication of success or failure.
|
||||
* @remark Assumes caller has aquired the appropriate lock first.
|
||||
*/
|
||||
BOOL list_remove_node(LIST * list, NODE * node)
|
||||
BOOL list_remove_node(PLIST pList, PNODE pNode)
|
||||
{
|
||||
if (list == NULL || node == NULL)
|
||||
if (pList == NULL || pNode == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (list->count - 1 == 0)
|
||||
if (pList->count - 1 == 0)
|
||||
{
|
||||
list->start = NULL;
|
||||
list->end = NULL;
|
||||
pList->start = NULL;
|
||||
pList->end = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list->start == node)
|
||||
if (pList->start == pNode)
|
||||
{
|
||||
list->start = list->start->next;
|
||||
list->start->prev = NULL;
|
||||
pList->start = pList->start->next;
|
||||
pList->start->prev = NULL;
|
||||
}
|
||||
else if (list->end == node)
|
||||
else if (pList->end == pNode)
|
||||
{
|
||||
list->end = list->end->prev;
|
||||
list->end->next = NULL;
|
||||
pList->end = pList->end->prev;
|
||||
pList->end->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->next->prev = node->prev;
|
||||
node->prev->next = node->next;
|
||||
pNode->next->prev = pNode->prev;
|
||||
pNode->prev->next = pNode->next;
|
||||
}
|
||||
}
|
||||
|
||||
list->count -= 1;
|
||||
pList->count -= 1;
|
||||
|
||||
node->next = NULL;
|
||||
pNode->next = NULL;
|
||||
|
||||
node->prev = NULL;
|
||||
pNode->prev = NULL;
|
||||
|
||||
free(node);
|
||||
free(pNode);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Remove a given data item from the list.
|
||||
* @param list Pointer to the \c LIST to remove the item from.
|
||||
* @param pList Pointer to the \c LIST to remove the item from.
|
||||
* @param data The data that is to be removed from the list.
|
||||
* @remark Assumes data items are unqique as only the first occurrence is removed.
|
||||
* @returns Indication of success or failure.
|
||||
* @sa list_remove_node
|
||||
*/
|
||||
BOOL list_remove(LIST * list, LPVOID data)
|
||||
BOOL list_remove(PLIST pList, LPVOID data)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
NODE * current_node = NULL;
|
||||
PNODE current_node = NULL;
|
||||
|
||||
if (list == NULL || data == NULL)
|
||||
if (pList == NULL || data == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lock_acquire(list->lock);
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
current_node = list->start;
|
||||
current_node = pList->start;
|
||||
|
||||
while (current_node != NULL)
|
||||
{
|
||||
@ -236,41 +237,41 @@ BOOL list_remove(LIST * list, LPVOID data)
|
||||
current_node = current_node->next;
|
||||
}
|
||||
|
||||
result = list_remove_node(list, current_node);
|
||||
result = list_remove_node(pList, current_node);
|
||||
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Remove a list item at the specified index.
|
||||
* @param list Pointer to the \c LIST to remove the item from.
|
||||
* @param pList Pointer to the \c LIST to remove the item from.
|
||||
* @param index Index of the item to remove.
|
||||
* @returns Indication of success or failure.
|
||||
*/
|
||||
BOOL list_delete(LIST * list, DWORD index)
|
||||
BOOL list_delete(PLIST pList, DWORD index)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
LPVOID data = NULL;
|
||||
NODE * current_node = NULL;
|
||||
PNODE current_node = NULL;
|
||||
|
||||
if (list == NULL)
|
||||
if (pList == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lock_acquire(list->lock);
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
if (list->count > index)
|
||||
if (pList->count > index)
|
||||
{
|
||||
current_node = list->start;
|
||||
current_node = pList->start;
|
||||
|
||||
while (current_node != NULL)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
result = list_remove_node(list, current_node);
|
||||
result = list_remove_node(pList, current_node);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -280,111 +281,137 @@ BOOL list_delete(LIST * list, DWORD index)
|
||||
}
|
||||
}
|
||||
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Push a data item onto the end of the list.
|
||||
* @param list Pointer to the \c LIST to append the data to.
|
||||
* @param pList Pointer to the \c LIST to append the data to.
|
||||
* @param data Pointer to the data to append.
|
||||
* @returns Indication of success or failure.
|
||||
*/
|
||||
BOOL list_push(LIST * list, LPVOID data)
|
||||
BOOL list_push(PLIST pList, LPVOID data)
|
||||
{
|
||||
NODE * node = NULL;
|
||||
PNODE pNode = NULL;
|
||||
|
||||
if (list == NULL)
|
||||
if (pList == NULL)
|
||||
return FALSE;
|
||||
|
||||
node = (NODE*)malloc(sizeof(NODE));
|
||||
if (node == NULL)
|
||||
pNode = (PNODE)malloc(sizeof(NODE));
|
||||
if (pNode == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
node->data = data;
|
||||
node->next = NULL;
|
||||
node->prev = NULL;
|
||||
pNode->data = data;
|
||||
pNode->next = NULL;
|
||||
pNode->prev = NULL;
|
||||
|
||||
lock_acquire(list->lock);
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
if (list->end != NULL)
|
||||
if (pList->end != NULL)
|
||||
{
|
||||
list->end->next = node;
|
||||
pList->end->next = pNode;
|
||||
|
||||
node->prev = list->end;
|
||||
pNode->prev = pList->end;
|
||||
|
||||
list->end = node;
|
||||
pList->end = pNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
list->start = node;
|
||||
list->end = node;
|
||||
pList->start = pNode;
|
||||
pList->end = pNode;
|
||||
}
|
||||
|
||||
list->count += 1;
|
||||
pList->count += 1;
|
||||
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Pop a data value off the end of the list.
|
||||
* @param list Pointer to the \c LIST to pop the value from.
|
||||
* @param pList Pointer to the \c LIST to pop the value from.
|
||||
* @returns The popped value.
|
||||
* @retval NULL Indicates no data in the list.
|
||||
*/
|
||||
LPVOID list_pop(LIST * list)
|
||||
LPVOID list_pop(PLIST pList)
|
||||
{
|
||||
LPVOID data = NULL;
|
||||
|
||||
if (list == NULL)
|
||||
if (pList == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lock_acquire(list->lock);
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
if (list->end != NULL)
|
||||
if (pList->end != NULL)
|
||||
{
|
||||
data = list->end->data;
|
||||
data = pList->end->data;
|
||||
|
||||
list_remove_node(list, list->end);
|
||||
list_remove_node(pList, pList->end);
|
||||
}
|
||||
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Pop a data value off the start of the list.
|
||||
* @param list Pointer to the \c LIST to shift the value from.
|
||||
* @param pList Pointer to the \c LIST to shift the value from.
|
||||
* @returns The shifted value.
|
||||
* @retval NULL Indicates no data in the list.
|
||||
*/
|
||||
LPVOID list_shift(LIST * list)
|
||||
LPVOID list_shift(PLIST pList)
|
||||
{
|
||||
LPVOID data = NULL;
|
||||
|
||||
if (list == NULL)
|
||||
if (pList == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lock_acquire(list->lock);
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
if (list->start != NULL)
|
||||
if (pList->start != NULL)
|
||||
{
|
||||
data = list->start->data;
|
||||
data = pList->start->data;
|
||||
|
||||
list_remove_node(list, list->start);
|
||||
list_remove_node(pList, pList->start);
|
||||
}
|
||||
|
||||
lock_release(list->lock);
|
||||
lock_release(pList->lock);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Iterate over the list and call a function callback on each element.
|
||||
* @param pList Pointer to the \c LIST to enumerate.
|
||||
* @param pCallback Callback function to invoke for each element in the list.
|
||||
* @param pState Pointer to the state to pass with each function call.
|
||||
*/
|
||||
VOID list_enumerate(PLIST pList, PLISTENUMCALLBACK pCallback, LPVOID pState)
|
||||
{
|
||||
if (pList == NULL || pCallback == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock_acquire(pList->lock);
|
||||
|
||||
PNODE pCurrent = pList->start;
|
||||
|
||||
while (pCurrent != NULL)
|
||||
{
|
||||
pCallback(pState, pCurrent->data);
|
||||
pCurrent = pCurrent->next;
|
||||
}
|
||||
|
||||
lock_release(pList->lock);
|
||||
}
|
@ -11,7 +11,7 @@ typedef struct _NODE
|
||||
struct _NODE * next; ///< Pointer to the next node in the list.
|
||||
struct _NODE * prev; ///< Pointer to the previous node in the list.
|
||||
LPVOID data; ///< Reference to the data in the list node.
|
||||
} NODE;
|
||||
} NODE, *PNODE;
|
||||
|
||||
/*! @brief Container structure for a list instance. */
|
||||
typedef struct _LIST
|
||||
@ -20,17 +20,20 @@ typedef struct _LIST
|
||||
NODE * end; ///< Pointer to the last node in the list.
|
||||
DWORD count; ///< Count of elements in the list.
|
||||
LOCK * lock; ///< Reference to the list's synchronisation lock.
|
||||
} LIST;
|
||||
} LIST, *PLIST;
|
||||
|
||||
typedef VOID(*PLISTENUMCALLBACK)(LPVOID pState, LPVOID pData);
|
||||
|
||||
LIST * list_create(VOID);
|
||||
VOID list_destroy(LIST * list);
|
||||
DWORD list_count(LIST * list);
|
||||
LPVOID list_get(LIST * list, DWORD index);
|
||||
BOOL list_add(LIST * list, LPVOID data);
|
||||
BOOL list_remove(LIST * list, LPVOID data);
|
||||
BOOL list_delete(LIST * list, DWORD index);
|
||||
BOOL list_push(LIST * list, LPVOID data);
|
||||
LPVOID list_pop(LIST * list);
|
||||
LPVOID list_shift(LIST * list);
|
||||
VOID list_destroy(PLIST pList);
|
||||
DWORD list_count(PLIST pList);
|
||||
LPVOID list_get(PLIST pList, DWORD index);
|
||||
BOOL list_add(PLIST pList, LPVOID data);
|
||||
BOOL list_remove(PLIST pList, LPVOID data);
|
||||
BOOL list_delete(PLIST pList, DWORD index);
|
||||
BOOL list_push(PLIST pList, LPVOID data);
|
||||
LPVOID list_pop(PLIST pList);
|
||||
LPVOID list_shift(PLIST pList);
|
||||
VOID list_enumerate(PLIST pList, PLISTENUMCALLBACK pCallback, LPVOID pState);
|
||||
|
||||
#endif
|
@ -8,7 +8,6 @@
|
||||
#include "video.h"
|
||||
#include "screen.h"
|
||||
|
||||
|
||||
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
|
||||
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
|
||||
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
|
||||
@ -28,8 +27,10 @@ Command customCommands[] =
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the server extension
|
||||
/*!
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -40,12 +41,26 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialize the server extension
|
||||
/*!
|
||||
* @brief Deinitialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
{
|
||||
command_deregister_all( customCommands );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "espia", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -40,10 +40,9 @@ Command customCommands[] =
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief Initialize the server extension
|
||||
* @details Registers all the extended API commands.
|
||||
* @param remote Pointer to the \c Remote initialising the extension.
|
||||
* @returns Always returns \c ERROR_SUCCESS.
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -59,9 +58,8 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
|
||||
/*!
|
||||
* @brief Deinitialize the server extension.
|
||||
* @details Unregisters all the extended API commands.
|
||||
* @param remote Pointer to the \c Remote destroying the extension.
|
||||
* @returns Always returns \c ERROR_SUCCESS.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -69,3 +67,15 @@ DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "extapi", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
@ -207,8 +207,10 @@ Command customCommands[] =
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the server extension
|
||||
/*!
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -219,8 +221,10 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialize the server extension
|
||||
/*!
|
||||
* @brief Deinitialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -228,3 +232,15 @@ DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "incognito", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -206,9 +206,9 @@ DWORD request_wifi_profile_list(Remote *remote, Packet *packet)
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Initialises the server extension.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @returns \c ERROR_SUCCESS
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -226,14 +226,26 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Deinitialises the server extension.
|
||||
* @param remote Pointer to the \c Remote instance.
|
||||
* @returns \c ERROR_SUCCESS
|
||||
* @brief Deinitialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
{
|
||||
mimikatz_init_or_clean(FALSE);
|
||||
command_deregister_all(customCommands);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "kiwi", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
@ -18,7 +18,8 @@ void* dhcpserver = NULL; //global DHCP server pointer
|
||||
void* tftpserver = NULL; //global TFTP server pointer
|
||||
|
||||
//Launches the DHCP server
|
||||
DWORD request_lanattacks_start_dhcp(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_start_dhcp(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
||||
int res = startDHCPServer(dhcpserver);
|
||||
@ -29,7 +30,8 @@ DWORD request_lanattacks_start_dhcp(Remote *remote, Packet *packet){
|
||||
}
|
||||
|
||||
//Reset the DHCP server
|
||||
DWORD request_lanattacks_reset_dhcp(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_reset_dhcp(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
||||
destroyDHCPServer(dhcpserver);
|
||||
@ -39,18 +41,24 @@ DWORD request_lanattacks_reset_dhcp(Remote *remote, Packet *packet){
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
//Set a DHCP option based on the name and value specified in the packet
|
||||
DWORD request_lanattacks_set_dhcp_option(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_set_dhcp_option(Remote *remote, Packet *packet)
|
||||
{
|
||||
DWORD retval = ERROR_SUCCESS;
|
||||
char* name = NULL;
|
||||
unsigned int namelen = 0;
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
||||
do{
|
||||
do
|
||||
{
|
||||
//Get option value
|
||||
Tlv tlv;
|
||||
if((retval = packet_get_tlv(packet, TLV_TYPE_LANATTACKS_OPTION, &tlv)) != ERROR_SUCCESS)
|
||||
if ((retval = packet_get_tlv(packet, TLV_TYPE_LANATTACKS_OPTION, &tlv)) != ERROR_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//Get option name
|
||||
name = packet_get_tlv_value_string(packet, TLV_TYPE_LANATTACKS_OPTION_NAME);
|
||||
namelen = (unsigned int)strlen(name);
|
||||
@ -62,7 +70,8 @@ DWORD request_lanattacks_set_dhcp_option(Remote *remote, Packet *packet){
|
||||
}
|
||||
|
||||
//Turns off the DHCP server
|
||||
DWORD request_lanattacks_stop_dhcp(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_stop_dhcp(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
||||
int res = stopDHCPServer(dhcpserver);
|
||||
@ -71,8 +80,10 @@ DWORD request_lanattacks_stop_dhcp(Remote *remote, Packet *packet){
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
//Gets and resets the DHCP log
|
||||
DWORD request_lanattacks_dhcp_log(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_dhcp_log(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
||||
unsigned long loglen;
|
||||
@ -86,7 +97,8 @@ DWORD request_lanattacks_dhcp_log(Remote *remote, Packet *packet){
|
||||
}
|
||||
|
||||
//Launches the TFTP server
|
||||
DWORD request_lanattacks_start_tftp(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_start_tftp(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
||||
int res = startTFTPServer(tftpserver);
|
||||
@ -97,7 +109,8 @@ DWORD request_lanattacks_start_tftp(Remote *remote, Packet *packet){
|
||||
}
|
||||
|
||||
//Reset the TFTP server
|
||||
DWORD request_lanattacks_reset_tftp(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_reset_tftp(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
||||
destroyTFTPServer(tftpserver);
|
||||
@ -109,7 +122,8 @@ DWORD request_lanattacks_reset_tftp(Remote *remote, Packet *packet){
|
||||
}
|
||||
|
||||
//Adds a file to serve based on the name and value specified in the packet
|
||||
DWORD request_lanattacks_add_tftp_file(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_add_tftp_file(Remote *remote, Packet *packet)
|
||||
{
|
||||
DWORD retval = ERROR_SUCCESS;
|
||||
char* name = NULL;
|
||||
unsigned int namelen = 0;
|
||||
@ -118,8 +132,11 @@ DWORD request_lanattacks_add_tftp_file(Remote *remote, Packet *packet){
|
||||
do{
|
||||
Tlv tlv;
|
||||
//Get file contents
|
||||
if((retval = packet_get_tlv(packet, TLV_TYPE_LANATTACKS_RAW, &tlv)) != ERROR_SUCCESS)
|
||||
if ((retval = packet_get_tlv(packet, TLV_TYPE_LANATTACKS_RAW, &tlv)) != ERROR_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//Get file name
|
||||
name = packet_get_tlv_value_string(packet, TLV_TYPE_LANATTACKS_OPTION_NAME);
|
||||
namelen = (unsigned int)strlen(name);
|
||||
@ -131,7 +148,8 @@ DWORD request_lanattacks_add_tftp_file(Remote *remote, Packet *packet){
|
||||
}
|
||||
|
||||
//Turns off the TFTP server
|
||||
DWORD request_lanattacks_stop_tftp(Remote *remote, Packet *packet){
|
||||
DWORD request_lanattacks_stop_tftp(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
|
||||
int res = stopTFTPServer(tftpserver);
|
||||
@ -140,6 +158,7 @@ DWORD request_lanattacks_stop_tftp(Remote *remote, Packet *packet){
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
Command customCommands[] =
|
||||
{
|
||||
COMMAND_REQ( "lanattacks_start_dhcp", request_lanattacks_start_dhcp ),
|
||||
@ -154,8 +173,10 @@ Command customCommands[] =
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the server extension
|
||||
/*!
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote) {
|
||||
hMetSrv = remote->hMetSrv;
|
||||
@ -165,15 +186,18 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote) {
|
||||
dhcpserver = createDHCPServer();
|
||||
tftpserver = createTFTPServer();
|
||||
|
||||
if (tftpserver) {
|
||||
if (tftpserver)
|
||||
{
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialize the server extension
|
||||
/*!
|
||||
* @brief Deinitialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -187,3 +211,15 @@ DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "lanattacks", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -92,8 +92,10 @@ Command customCommands[] =
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the server extension
|
||||
/*!
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -104,8 +106,10 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialize the server extension
|
||||
/*!
|
||||
* @brief Deinitialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -113,4 +117,17 @@ DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "mimikatz", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,8 +27,10 @@ Command customCommands[] =
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief Initialize the `priv` server extension.
|
||||
*/
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
{
|
||||
hMetSrv = remote->hMetSrv;
|
||||
@ -39,11 +41,25 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Deinitialize the `priv` server extension.
|
||||
*/
|
||||
* @brief Deinitialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
{
|
||||
command_deregister_all(customCommands);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "priv", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -1192,8 +1192,10 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the server extension
|
||||
/*!
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -1264,8 +1266,10 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialize the server extension
|
||||
/*!
|
||||
* @brief Deinitialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
{
|
||||
@ -1283,3 +1287,15 @@ DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
lock_destroy(snifferm);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "sniffer", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
@ -175,8 +175,10 @@ Command customCommands[] =
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the server extension
|
||||
/*!
|
||||
* @brief Initialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
|
||||
@ -192,8 +194,10 @@ DWORD InitServerExtension(Remote *remote)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialize the server extension
|
||||
/*!
|
||||
* @brief Deinitialize the server extension.
|
||||
* @param remote Pointer to the remote instance.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
|
||||
@ -205,3 +209,15 @@ DWORD DeinitServerExtension(Remote *remote)
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the name of the extension.
|
||||
* @param buffer Pointer to the buffer to write the name to.
|
||||
* @param bufferSize Size of the \c buffer parameter.
|
||||
* @return Indication of success or failure.
|
||||
*/
|
||||
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
|
||||
{
|
||||
strncpy_s(buffer, bufferSize, "stdapi", bufferSize - 1);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -15,9 +15,7 @@
|
||||
#ifdef _WIN32
|
||||
DWORD __declspec(dllexport) Init(SOCKET fd)
|
||||
{
|
||||
|
||||
return server_setup(fd);
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
|
@ -32,12 +32,15 @@
|
||||
DWORD server_setup(SOCKET fd);
|
||||
typedef DWORD (*PSRVINIT)(Remote *remote);
|
||||
typedef DWORD (*PSRVDEINIT)(Remote *remote);
|
||||
typedef DWORD (*PSRVGETNAME)(char* buffer, int bufferSize);
|
||||
|
||||
typedef struct _EXTENSION
|
||||
{
|
||||
HMODULE library;
|
||||
PSRVINIT init;
|
||||
PSRVDEINIT deinit;
|
||||
} EXTENSION;
|
||||
PSRVGETNAME getname;
|
||||
char name[16];
|
||||
} EXTENSION, *PEXTENSION;
|
||||
|
||||
#endif
|
||||
|
@ -1,28 +1,11 @@
|
||||
#ifndef _METERPRETER_SERVER_REMOTE_DISPATCHER_H
|
||||
#define _METERPRETER_SERVER_REMOTE_DISPATCHER_H
|
||||
|
||||
|
||||
/*
|
||||
* core_loadlib
|
||||
* ------------
|
||||
*
|
||||
* Load a library into the address space of the executing process.
|
||||
*
|
||||
* TLVs:
|
||||
*
|
||||
* req: TLV_TYPE_LIBRARY_PATH -- The path of the library to load.
|
||||
* req: TLV_TYPE_FLAGS -- Library loading flags.
|
||||
* opt: TLV_TYPE_TARGET_PATH -- The contents of the library if uploading.
|
||||
* opt: TLV_TYPE_DATA -- The contents of the library if uploading.
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* - Implement in-memory library loading
|
||||
*/
|
||||
DWORD request_core_loadlib(Remote *remote, Packet *packet);
|
||||
DWORD request_core_listextensions(Remote* pRemote, Packet* pPacket);
|
||||
DWORD request_core_loadlib(Remote *pRemote, Packet *pPacket);
|
||||
|
||||
|
||||
VOID register_dispatch_routines();
|
||||
VOID deregister_dispatch_routines( Remote * remote );
|
||||
VOID deregister_dispatch_routines(Remote * remote);
|
||||
|
||||
#endif
|
||||
|
@ -5,16 +5,13 @@
|
||||
extern HINSTANCE hAppInstance;
|
||||
#endif
|
||||
|
||||
/**************************
|
||||
* Core dispatch routines *
|
||||
**************************/
|
||||
|
||||
LIST * extension_list = NULL;
|
||||
PLIST gExtensionList = NULL;
|
||||
|
||||
// Dispatch table
|
||||
Command customCommands[] =
|
||||
{
|
||||
COMMAND_REQ( "core_loadlib", request_core_loadlib ),
|
||||
COMMAND_REQ("core_loadlib", request_core_loadlib),
|
||||
COMMAND_REQ("core_listextensions", request_core_listextensions),
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
|
||||
@ -23,28 +20,30 @@ Command customCommands[] =
|
||||
*/
|
||||
VOID register_dispatch_routines()
|
||||
{
|
||||
extension_list = list_create();
|
||||
gExtensionList = list_create();
|
||||
|
||||
command_register_all( customCommands );
|
||||
command_register_all(customCommands);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deregisters previously registered custom commands and loaded extensions.
|
||||
*/
|
||||
VOID deregister_dispatch_routines( Remote * remote )
|
||||
VOID deregister_dispatch_routines(Remote * remote)
|
||||
{
|
||||
while( TRUE )
|
||||
while (TRUE)
|
||||
{
|
||||
EXTENSION * extension = list_pop( extension_list );
|
||||
if( !extension )
|
||||
PEXTENSION extension = list_pop(gExtensionList);
|
||||
if (!extension)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
extension->deinit( remote );
|
||||
extension->deinit(remote);
|
||||
|
||||
free( extension );
|
||||
free(extension);
|
||||
}
|
||||
|
||||
command_deregister_all( customCommands );
|
||||
command_deregister_all(customCommands);
|
||||
|
||||
list_destroy( extension_list );
|
||||
list_destroy(gExtensionList);
|
||||
}
|
||||
|
@ -4,13 +4,71 @@
|
||||
extern HINSTANCE hAppInstance;
|
||||
|
||||
// see remote_dispatch_common.c
|
||||
extern LIST * extension_list;
|
||||
extern PLIST gExtensionList;
|
||||
// see common/base.c
|
||||
extern Command *extensionCommands;
|
||||
|
||||
DWORD request_core_loadlib(Remote *remote, Packet *packet)
|
||||
VOID extension_list_callback(LPVOID pState, LPVOID pData)
|
||||
{
|
||||
Packet *response = packet_create_response(packet);
|
||||
Packet* pResponse = (Packet*)pState;
|
||||
|
||||
if (pResponse != NULL && pData != NULL)
|
||||
{
|
||||
PEXTENSION pExt = (PEXTENSION)pData;
|
||||
if (pExt->name[0] != '\0')
|
||||
{
|
||||
dprintf("[LISTEXT] Adding extension: %s", pExt->name);
|
||||
packet_add_tlv_string(pResponse, TLV_TYPE_STRING, pExt->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD request_core_listextensions(Remote* pRemote, Packet* pPacket)
|
||||
{
|
||||
Packet* response = packet_create_response(pPacket);
|
||||
DWORD res = ERROR_SUCCESS;
|
||||
|
||||
if (response)
|
||||
{
|
||||
dprintf("[LISTEXT] Listing extensions ...");
|
||||
// Start by enumerating the names of the extensions
|
||||
list_enumerate(gExtensionList, extension_list_callback, response);
|
||||
|
||||
// then iterate through the list of registered commands so that the attacker
|
||||
// knows what is available.
|
||||
for (Command* pCommand = extensionCommands; pCommand != NULL; pCommand = pCommand->next)
|
||||
{
|
||||
dprintf("[LISTEXT] Adding command: %s", pCommand->method);
|
||||
packet_add_tlv_string(response, TLV_TYPE_METHOD, pCommand->method);
|
||||
}
|
||||
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, res);
|
||||
packet_transmit(pRemote, response, NULL);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* core_loadlib
|
||||
* ------------
|
||||
*
|
||||
* Load a library into the address space of the executing process.
|
||||
*
|
||||
* TLVs:
|
||||
*
|
||||
* req: TLV_TYPE_LIBRARY_PATH -- The path of the library to load.
|
||||
* req: TLV_TYPE_FLAGS -- Library loading flags.
|
||||
* opt: TLV_TYPE_TARGET_PATH -- The contents of the library if uploading.
|
||||
* opt: TLV_TYPE_DATA -- The contents of the library if uploading.
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* - Implement in-memory library loading
|
||||
*/
|
||||
DWORD request_core_loadlib(Remote *pRemote, Packet *pPacket)
|
||||
{
|
||||
Packet *response = packet_create_response(pPacket);
|
||||
DWORD res = ERROR_SUCCESS;
|
||||
HMODULE library;
|
||||
PCHAR libraryPath;
|
||||
@ -22,8 +80,8 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet)
|
||||
|
||||
do
|
||||
{
|
||||
libraryPath = packet_get_tlv_value_string(packet, TLV_TYPE_LIBRARY_PATH);
|
||||
flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS);
|
||||
libraryPath = packet_get_tlv_value_string(pPacket, TLV_TYPE_LIBRARY_PATH);
|
||||
flags = packet_get_tlv_value_uint(pPacket, TLV_TYPE_FLAGS);
|
||||
|
||||
// Invalid library path?
|
||||
if (!libraryPath)
|
||||
@ -39,9 +97,9 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet)
|
||||
Tlv dataTlv;
|
||||
|
||||
// Get the library's file contents
|
||||
if ((packet_get_tlv(packet, TLV_TYPE_DATA,
|
||||
if ((packet_get_tlv(pPacket, TLV_TYPE_DATA,
|
||||
&dataTlv) != ERROR_SUCCESS) ||
|
||||
(!(targetPath = packet_get_tlv_value_string(packet,
|
||||
(!(targetPath = packet_get_tlv_value_string(pPacket,
|
||||
TLV_TYPE_TARGET_PATH))))
|
||||
{
|
||||
res = ERROR_INVALID_PARAMETER;
|
||||
@ -80,21 +138,26 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet)
|
||||
|
||||
// If a previous operation failed, break out.
|
||||
if (res != ERROR_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Load the library
|
||||
if ((!library) && (!(library = LoadLibrary(libraryPath))))
|
||||
if (!library && !(library = LoadLibrary(libraryPath)))
|
||||
{
|
||||
res = GetLastError();
|
||||
else
|
||||
res = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// If this library is supposed to be an extension library, try to
|
||||
// call its Init routine
|
||||
if ((flags & LOAD_LIBRARY_FLAG_EXTENSION) && (library))
|
||||
if ((flags & LOAD_LIBRARY_FLAG_EXTENSION) && library)
|
||||
{
|
||||
EXTENSION * extension = (EXTENSION *)malloc(sizeof(EXTENSION));
|
||||
PEXTENSION extension = (PEXTENSION)malloc(sizeof(EXTENSION));
|
||||
|
||||
if (extension)
|
||||
{
|
||||
memset(extension, 0, sizeof(EXTENSION));
|
||||
|
||||
extension->library = library;
|
||||
|
||||
// if the library was loaded via its reflective loader we must use GetProcAddressR()
|
||||
@ -102,34 +165,42 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet)
|
||||
{
|
||||
extension->init = (PSRVINIT)GetProcAddressR(extension->library, "InitServerExtension");
|
||||
extension->deinit = (PSRVDEINIT)GetProcAddressR(extension->library, "DeinitServerExtension");
|
||||
extension->getname = (PSRVGETNAME)GetProcAddressR(extension->library, "GetExtensionName");
|
||||
}
|
||||
else
|
||||
{
|
||||
extension->init = (PSRVINIT)GetProcAddress(extension->library, "InitServerExtension");
|
||||
extension->deinit = (PSRVDEINIT)GetProcAddress(extension->library, "DeinitServerExtension");
|
||||
extension->getname = (PSRVGETNAME)GetProcAddress(extension->library, "GetExtensionName");
|
||||
}
|
||||
|
||||
// patch in the metsrv.dll's HMODULE handle, used by the server extensions for delay loading
|
||||
// functions from the metsrv.dll library. We need to do it this way as LoadLibrary/GetProcAddress
|
||||
// wont work if we have used Reflective DLL Injection as metsrv.dll will be 'invisible' to these functions.
|
||||
remote->hMetSrv = hAppInstance;
|
||||
pRemote->hMetSrv = hAppInstance;
|
||||
|
||||
// Call the init routine in the library
|
||||
if (extension->init)
|
||||
{
|
||||
dprintf("[SERVER] Calling init()...");
|
||||
|
||||
res = extension->init(remote);
|
||||
res = extension->init(pRemote);
|
||||
|
||||
if (res == ERROR_SUCCESS)
|
||||
{
|
||||
list_push(extension_list, extension);
|
||||
if (extension->getname)
|
||||
{
|
||||
extension->getname(extension->name, sizeof(extension->name));
|
||||
}
|
||||
|
||||
list_push(gExtensionList, extension);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(extension);
|
||||
}
|
||||
}
|
||||
|
||||
dprintf("[SERVER] Called init()...");
|
||||
if (response)
|
||||
{
|
||||
@ -146,7 +217,7 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet)
|
||||
if (response)
|
||||
{
|
||||
packet_add_tlv_uint(response, TLV_TYPE_RESULT, res);
|
||||
packet_transmit(remote, response, NULL);
|
||||
packet_transmit(pRemote, response, NULL);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
Loading…
Reference in New Issue
Block a user