TokenHeist: Stealing Windows Access Tokens for fun and education
Learn how to steal Windows Access Tokens and use them to impersonate high privilege users.
After familiarizing ourselves with Windows Access Tokens and what makes a token valuable, the next step is to steal them, obviously.
In this post, I will show you how to perform a perfect Token Heist.
Note: The usage of the word “perfect” was purely for aesthetic purposes. We are in learning mode so there’s bound to be some noise.
First, lets understand what is required to perform a token heist. In order for a process to be able to access and duplicate (or impersonate) a token from another process, it needs to have SeDebugPrivilege
and SeImpersonatePrivilege
(or SeAssignPrimaryTokenPrivilege
) privileges. The SeDebugPrivilege
allows a process to open other processes with PROCESS_QUERY_INFORMATION
and PROCESS_VM_READ
rights, which are necessary for extracting sensitive information, such as access tokens. The SeImpersonatePrivilege
enables the duplication and assignment of a stolen token to a new process. These permissions are usually available with processes running with administrator or other high-privilege context. However, having a high-privilege context is not always necessary to steal and impersonate a token (more on this later).
In summary, to be able to perform the Token Heist our process needs to have the following:
SeDebugPrivilge
(almost always required).SeImpersonatePrivilege
(must have in all cases).High-privilege context (may not be required in certain cases).
Note: Even if the attacker process has SeImpersonatePrivilege
and SeDebugPrivilege
, it cannot steal the token of a Protected Process (PP) or Protected Process Light (PPL) due to kernel-enforced restrictions.
Next, lets have a look at the apparatus (i.e. Windows APIs) that we are going to need to be able to execute this heist. We are going to rely on following Windows APIs for our heist:
OpenProcess()
: Opens a handle to a target process.OpenProcessToken()
: Retrieves a handle to the process's primary token.DuplicateTokenEx()
: Duplicates the stolen token, allowing the attacker to create an impersonation or primary token.CreateProcessWithTokenW()
: Uses a duplicated token to launch a new process in the context of another user.
Armed with this information, we are now ready to execute our Token Heist. I created a simple tool for this, TokenHeist.
Note: I occasionally use generative AI to create red team tools. This is my experiment to demonstrate how generative AI can be leveraged to build custom tools on the fly and help bypass signature based detection. Every piece of code that I share is thoroughly reviewed and tested in my lab. You may or may not agree with this approach. I respect your views. If you’d like to share them, please reach out via email or other channels mentioned below.
This tool requires the user to specify a process name using —process or -p flag. It then performs the following steps:
Checks the current process for
SeDebugPrivilege
andSeImpersonatePrivilege
. If the privileges are present but disabled, it enables them.Retrieves the process ID of the specified process.
Obtains it’s process handle.
Obtains it’s token handle.
Duplicates the token.
Launches cmd.exe with the stolen token.

Red Team Notes
- To steal a token the source process must have SeDebugPrivilege, SeImpersonatePrivilege and should be running with high-privilege context.
- We can use OpenProcess(), OpenProcessToken(), DuplicateTokenEx() and CreateProcessWithTokenW() Windows APIs to steal and impersonate a token.
- TokenHeist is a simple tool to demonstrate stealing and impersonating a token.
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.