Using VirtualAllocEx and WriteProcessMemory

Overview

Process injection is a technique used to inject code into a running process on a target machine. This can be done to evade AV/EDRs as well as maintaining persistence on a target machine.

This technique leverages the following below kernel32 APIs.

Win32 Api's

OpenProcess - Open the target process

VirtualAllocEx - To allocate memory within the target process.

WriteProcessMemory - To copy shellcode to target

CreateRemoteThread - To execute shellcode

Optional

GetProcessesByName - Get a handle to the target process

Walkthrough

  1. First, we will need to get a handle on the remote process.

  2. Secondly, we open a handle to that process.

  3. We then need to allocate memory within the target process.

  4. We can then copy our shellcode into the memory address.

  5. Lastly, we need to execute the shellcode in the remote thread.

Code

Detection and AV

Detection on nt-PInject code without shellcode:

Details

Getting a handle to the target process

Target process for this example explorer.exe

Getting a handle on explorer process that we will inject into:

Open the target process

The first argument dwDesiredAccess is the access right we want to obtain for the remote process.

Based on the pinvoke documentation, the required access we want is All = 0x001F0FFF

We can call the function requesting all access rights, with the PID of the process we aim to inject into:

Call VirtualAllocEx

hProcess our process handle retrieved from OpenProcess

lpAddress we can pass a null value and let the API select and unused address

dwSize the amount of memory to allocate

flAllocationType this parameter defines the type of memory allocation.

To reserve and commit pages in one step, call VirtualAlloc with MEM_COMMIT | MEM_RESERVE.

Since MEM_COMMIT = 0x00001000 and MEM_RESERVE = 0x00002000, we need to set this to 0x00003000

The first argument we will need to specify the handle to our target process hProcess

The second aregument lpAddress, we can pass a null value and let the API select an unused address

flProtect we want to configure this to PAGE_EXECUTE_READWRITE = 0x40

Call WriteProcessMemory

hProcess our process handle retrieved from OpenProcess

lpBaseAddress will be set to our addr pointer

lpBuffer point to our shellcode in the buff variable

nSize is the size of our shellcode

outsize is a destination pointer address to show the number of bytes written

Execute shellcode with CreateRemoteThread

hProcess our process handle retrieved from OpenProcess

lpThreadAttributes we can set this to zero to accept the default values

dwStackSize we can set this to zero, the new thread uses the default size for the executable

lpStardAdress this is the address of the buffer we allocated with VirtualAllocEx

lpParameter is a pointer to variables which be passed to the thread function pointed by lpStartAddress, since our shellcode does not need any parameters, we can pass a NULL here

dwCreationFlags allows creating the thread in a suspended state, we don't need it so we can set this to zero

lpThreadId a pointer to a variable that receives ther thread identifies, we can set to NULL

References

Last updated