The idea behind this IPC / write-primitive is utilizing the SetConsoleTitleA()
API to expose binary data between two processes.
This function does not need a handle to the remote process, instead, it only requires a Process ID.
While the memory can't really be written directly via this API function alone, execution-altering API functions can be utilized to redirect the execution to GetConsoleTitleA()
, which fetches the data from console title to an arbitrary memory location passed as argument.
In this PoC, GetThreadContext()
& SetThreadContext()
are used to alter the execution.
The injection is performed by 3 consecutive combinations of "Write/Exec"s:
- Write a pointer to a
jmp $
loop located inside the target process. - Write a pointer to the payload, and return to the
jmp $
loop. - Write the actual payload, which
RSP
will be pointing and returning to, thanks to the pointer written in the previous step.
The result is execution of a "PopCalc" shellcode.
- Address of a
0xeb, 0xfe
(jmp $
) loop. The PoC utilizes a static address fromkernelbase.dll
. - A big enough RWX memory region to replace the stack with (1MB will do). In this PoC, the memory is allocated via
VirtualAllocEx()
, but the handle to the target process is dropped immediately after. - (
THREAD_SET_CONTEXT
|THREAD_GET_CONTEXT
|THREAD_SUSPEND_RESUME
) access rights to the thread which execution will be altered. - The target process needs to be executed from
CMD.EXE
. Windows Terminal doesn't correctly fetch binary data from console title.
PopCalc shellcode by Bobby Cooke (boku).
This project is licensed under the MIT license. Copyrights are respective of each contributor listed at the beginning of each definition file.
Written with StackEdit.