Skip to main content

Overview

SeCreateTokenPrivilege allows a process to call the NtCreateToken syscall and create an entirely new access token from scratch. Unlike token duplication (which copies an existing token), this forges a token with arbitrary user SID, group memberships, privileges, and integrity level. You become whoever you want. This is one of the most powerful privileges in Windows. It is the digital equivalent of a blank government ID printer.

Who Has It by Default

In practice, almost nothing has this privilege. You will encounter it on:
  • Custom service accounts with misconfigured security policy
  • Third-party authentication/SSO products that create tokens for logged-on users
  • Backup/imaging software that restores user profiles with original SIDs
  • Compromised LSASS or SYSTEM contexts where you want to forge identities
If you have this privilege, you have won. The only question is what identity to forge. SYSTEM, Domain Admin, Enterprise Admin — pick one.

Check if Enabled

Expected output when exploitable:
If the state shows Disabled, the privilege is present in your token but not yet activated. You must enable it programmatically before calling NtCreateToken:
Verify:
Even when Disabled, the privilege only needs to be present in your token. Disabled is a soft toggle — any process can enable its own privileges via AdjustTokenPrivileges. If the privilege is not listed at all, you cannot use this technique.

How It Works Technically

The NtCreateToken Syscall

NtCreateToken is an undocumented ntdll function that creates a brand new access token. It is the only API that can build a token from individual components rather than deriving one from an existing logon session. Function signature:

What Each Parameter Controls

Why the Kernel Trusts This

The kernel checks exactly one thing before allowing NtCreateToken: does the calling token have SeCreateTokenPrivilege enabled? If yes, the syscall proceeds and builds whatever token you specify. There is no validation that the SIDs are legitimate, that the user exists, or that the privileges make sense. The kernel trusts you completely. This is by design — LSASS uses NtCreateToken after authenticating users to build their logon tokens. The assumption is that only LSASS would ever have this privilege.

Why It Is Extremely Dangerous

With SeCreateTokenPrivilege, you can forge a token that:
  1. Impersonates any local userAdministrator, SYSTEM, DefaultAccount
  2. Claims membership in any groupBUILTIN\Administrators, NT AUTHORITY\SYSTEM, Domain Admins
  3. Holds every privilege — all 35+ Windows privileges enabled, including SeTcbPrivilege, SeDebugPrivilege, SeAssignPrimaryTokenPrivilege
  4. Operates at SYSTEM integrity — bypasses UAC, mandatory integrity checks
  5. Uses any logon session — including the SYSTEM logon session (LUID 0x3e7)
  6. Cannot be distinguished from legitimate tokens — the kernel treats forged tokens identically to tokens created by LSASS
There is no higher privilege escalation path in Windows user-mode. This privilege is equivalent to being LSASS itself.

Using token-priv Toolset (hatRiot)

The token-priv project by hatRiot is the primary offensive toolset for exploiting Windows token privileges, including SeCreateTokenPrivilege.

Download

Project Structure

Compile with Visual Studio

Or open the solution in Visual Studio and build Release x64.

Usage — Forge a SYSTEM Token

The tool resolves NtCreateToken dynamically from ntdll and calls it with attacker-controlled parameters:
The default behavior creates a token with SYSTEM-level access and spawns a new command prompt running under that token.
The token-priv toolset focuses on demonstrating each privilege abuse individually. For production use during engagements, you may need to modify the source to customize the forged token’s SIDs, groups, and target process. The whitepaper (abusing_token_priv.pdf) in the repo documents the exact API calls and structures needed.

Manual Exploitation — C Implementation

Full implementation of NtCreateToken to forge an arbitrary token. This is the core technique regardless of which tool you use.

Resolving NtCreateToken

NtCreateToken is not exported by any import library. Resolve it at runtime from ntdll:

Required SID Definitions

Building the TOKEN_GROUPS Structure

Building the TOKEN_PRIVILEGES Structure

Calling NtCreateToken


Forging an Administrators Token

Create a token that identifies as the local Administrator with full group memberships. Use this when you need local admin access on a standalone machine.

SIDs Needed

Get Machine SID

Output example: S-1-5-21-3623811015-3361044348-30300820-500 The machine SID is everything except the final RID: S-1-5-21-3623811015-3361044348-30300820

Forge the Token

Spawn an Admin Shell


Forging a SYSTEM Token

The most common target. SYSTEM has unrestricted access to the local machine.

Required Parameters

Full C Code — Forge SYSTEM Token and Spawn cmd.exe

Compile


Forging a Domain Admin Token (Domain Context)

When the compromised machine is domain-joined, you can forge tokens with domain SIDs. This is devastating because no actual authentication to the DC occurs — the forged token is valid locally.

Get the Domain SID

Output: CORP\svc_backup S-1-5-21-1234567890-987654321-1122334455-1109 Domain SID: S-1-5-21-1234567890-987654321-1122334455
Or from any domain user:

Key Domain SIDs

Forge Domain Admin Token

A forged domain token is valid for local access checks on the compromised machine (file access, registry, service management, WMI). It will NOT authenticate to remote machines via Kerberos because no TGT exists. For network access, you still need credentials, a Kerberos ticket, or NTLM hash. Use this to escalate locally, then pivot using other techniques.

Impersonating the Forged Token

After forging a token with NtCreateToken, you need to use it. There are three primary methods.

Method 1 — ImpersonateLoggedOnUser (Current Thread)

Apply the token to the current thread. All subsequent API calls in this thread use the forged identity.

Method 2 — CreateProcessWithTokenW (New Process)

Spawn a new process running under the forged token. Requires SeImpersonatePrivilege in the calling token (or being SYSTEM).

Method 3 — CreateProcessAsUserW (New Process, Alternate)

Similar to CreateProcessWithTokenW but requires SeAssignPrimaryTokenPrivilege instead of SeImpersonatePrivilege. If your forged token includes this privilege, use it.

Method 4 — SetThreadToken (Specific Thread)

Apply the forged token to a specific thread rather than using ImpersonateLoggedOnUser:

Combining with SeImpersonatePrivilege

The most practical exploitation chain: SeCreateTokenPrivilege forges the token, SeImpersonatePrivilege lets you spawn processes under it.

Why You Need Both

If you only have SeCreateTokenPrivilege without SeImpersonatePrivilege:
  1. Forge a token that includes SeImpersonatePrivilege in its privileges list
  2. Use NtSetInformationThread with ThreadImpersonationToken to apply the impersonation token to the current thread (this bypasses the SeImpersonatePrivilege check in some scenarios)
  3. Or forge a token with SeAssignPrimaryTokenPrivilege and use CreateProcessAsUserW

Practical Chain

If You Lack SeImpersonatePrivilege

Forge a new token that includes SeImpersonatePrivilege, then use the lower-level approach:
On modern Windows (10+), the kernel performs additional security checks on impersonation tokens. The NtSetInformationThread bypass may not work on all builds. Test on the target OS version. If blocked, the most reliable approach is to include SeAssignPrimaryTokenPrivilege in the forged token and use CreateProcessAsUserW.

When You Encounter This in the Wild

Service Accounts

Third-party applications sometimes request SeCreateTokenPrivilege via Group Policy:
Check what accounts hold this right:

Common Scenarios

Identifying via WinPEAS

Identifying via PowerUp

Identifying via Seatbelt


Detection and Logging

Event IDs

What Triggers Alerts

  1. Event 4672 with SeCreateTokenPrivilege for any account other than SYSTEM or LSASS is highly anomalous
  2. Process lineage anomalies — a service account process spawning cmd.exe as SYSTEM
  3. Token integrity mismatch — a medium-integrity process creating a high-integrity or system-integrity token
  4. Unusual NtCreateToken syscalls — EDR/ETW can trace syscalls to ntdll

Sysmon Configuration for Detection

ETW Provider for Token Operations

Evasion Notes

  • The TokenSource field in NtCreateToken is logged — set it to something legitimate like "User32 " or "Advapi " instead of a custom string
  • NtCreateToken goes through the kernel, not a user-mode API — direct syscall stubs (SysWhispers) bypass ntdll hooking
  • The forged token’s logon session LUID is visible in Event 4624 — using SYSTEM_LUID makes the logon appear as a normal SYSTEM activity
  • Avoid spawning interactive processes — use ImpersonateLoggedOnUser for in-thread operations to reduce process creation events

Quick Reference