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
Use EXITFUNC=thread in msfvenom payload to not kill parent process on exit
Also setting it in multi/handler
msf6 exploit(multi/handler) > set exitfunc thread
Walkthrough
First, we will need to get a handle on the remote process.
Secondly, we open a handle to that process.
We then need to allocate memory within the target process.
We can then copy our shellcode into the memory address.
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