The steps to hijacking a local thread are as follows:
1.) Copy payload into a RWX buffer.
2.) Get a thread context that you want to hijack using the GetThreadContext() WinAPI or NT API equivalent. IMPORTANT: The thread must be in a suspended state.
3.) Set the Rip register to point to our buffer address
4.) Set the thread context using SetThreadContext() WINAPI or NTAPI equivilant.
5.) ResumeThread()
NOTE: In this example we are creating our own dummy thread in a suspended state. To suspend a thread, use SuspendThread(). Main threads cannot be Hijacked!
Hijacking a Remote Thread
Like we did for hijacking a local thread, we will create a dummy thread in a remote process. We can do this with CreateRemoteThread but it's a highly abused and monitored WINAPI function. Instead, we will use CreateProcess
Some important notes on CreateProcess:
lpApplicationName: Is the file name of the executable to open. Example: cmd.exe
lpCommandLine: The parameters for the specified lpApplicationName. Alternatively it can be the full file path w/ parameters. Example:C:/Windows/System32/cmd.exe /k whoami
Hijacking The Remote Thread
Once we have our Process and Thread handles from CreateDummyProcess(), we can allocate a remote buffer and copy our shellcode to it.
After our shellcodes been copied to our victim process we grab the thread context and assign the buffer address to the Rip register before callin SetThreadContext and ResumeThread.
WaitForSingleObject sets our thread into an alertable state. This prevents the thread from prematurely closing.