SeCreateTokenPrivilege: Token Forgery from Zero to SYSTEM

Found SeCreateTokenPrivilege on a non-system account? Create tokens with SID SYSTEM and Domain Admins from scratch. NtCreateToken for SYSTEM shell. Red Team technique.
- Posted on 2026-06-17
- Reading time: 4 min
You don't steal a token, you don't wait for connections. With SeCreateTokenPrivilege you call NtCreateToken() and forge a token with the SYSTEM SID, Domain Admins groups, and all the privileges you want—from scratch. If you see this on a non-system account: critical finding P0, document first of all.
Quick Exploit #
accesschk.exe -a SeCreateTokenPrivilege *
whoami /priv | findstr SeCreateTokenCreateToken.exe -user S-1-5-18 -groups S-1-5-32-544 -privs SeDebugPrivilege,SeImpersonatePrivilege
RunAs.exe -token [handle] cmd.exeExpected output:
nt authority\systemAttack Chain #
SeCreateTokenPrivilege su account non-SYSTEM trovato
→ PRIMO: documenta come finding critico (misconfiguration o backdoor)
→ token-priv PoC: CreateToken.exe -user S-1-5-18 -groups S-1-5-32-544
→ RunAs.exe con handle token → shell SYSTEM
OPPURE
→ token con SID Domain Admins → NTLM auth verso risorse di rete → DA
(NON funziona via Kerberos — PAC validation blocca i SID forgiati)Tool Decision #
| Target | Tool |
|---|---|
| Local SYSTEM token | CreateToken.exe -user S-1-5-18 da hatRiot/token-priv |
| Token with Domain Admin SID | CreateToken.exe + SID S-1-5-21-[DOMAIN]-512 |
| Check Domain Admins SID | wmic group where "name='Domain Admins'" get SID |
| Token for NTLM sidewall | Forge token + PTH/NTLM relay to network resources |
What is SeCreateTokenPrivilege? #
Allows you to call NtCreateToken() — the NT syscall that creates security token objects from scratch. A token created with this API can contain:
- Arbitrary user SID — SYSTEM, Administrator, any AD account
- Arbitrary group SIDs — Domain Admins, Enterprise Admins, any
- Arbitrary privileges — all SePrivilege series and beyond
- Arbitrary integrity level
All other token privileges work with existing tokens —they capture, inherit, or assign them. This creates them from scratch, without dependence on any external conditions.
Normally exclusive to: lsass.exe, services.exe, winlogon.exeIf you find it on a non-system account → critical finding to be documented immediately.
When it exists #
In a normal pentest, it's almost never on non-system accounts. If it appears:
- Core System Accounts — lsass.exe, services.exe (normal)
- Serious misconfiguration —explicitly assigned to a user or service account by mistake
- Previous Indicator of Compromise — backdoor installed by a previous attacker
Verify:
whoami /privLooking for:
SeCreateTokenPrivilege Create a token object EnabledInstant audit in the environment:
accesschk.exe -a SeCreateTokenPrivilege *If a non-SYSTEM account appears → document and mark as a critical finding before proceeding.
Step 1 — Exploit with token-priv PoC #
Use hatRiot's PoC collection, which includes implementations for SeCreateTokenPrivilege. Download from hatRiot/token-priv :
CreateToken.exe -user S-1-5-18 -groups S-1-5-32-544 -privs SeDebugPrivilege,SeImpersonatePrivilegeThe SID S-1-5-18 it's SYSTEM, S-1-5-32-544 is the local Administrators group.
Then start a process with the forged token:
RunAs.exe -token [handle] cmd.exeOutput:
nt authority\systemStep 2 — Add Domain Admin SID to the token #
The most useful case in AD: you create a token for a low-privilege account but add the Domain Admins SID:
Token forgiato:
UserSID: SID dell'account corrente (basso privilegio)
Groups: aggiungi S-1-5-21-[DOMAIN]-512 (Domain Admins) con SE_GROUP_ENABLED
Privs: aggiungi i privilegi necessariWith this token, NTLM authentication to domain resources is accepted as Domain Admin.
Critical limitation: With Kerberos , the DC validates the PAC (Privilege Attribute Certificate) signed with the domain keys. The forged token works for:
- Machine Local Resources
- NTLM authentication to network resources
Does not work for Kerberos authentication to network resources (real PAC is used).
Difference with SeTcbPrivilege #
| SeCreateTokenPrivilege | SeTcbPrivilege | |
|---|---|---|
| API | NtCreateToken (direct syscall) | LsaLogonUser (via LSA) |
| LSA logon session | ❌ Standalone token | ✅ Official session |
| Complexity | High | High |
In practice, both lead to the same result. The distinction is technical—relevant for those studying Windows internals.
Real-world scenarios #
Finding SeCreateTokenPrivilege on a non-SYSTEM account is almost always:
- Serious misconfiguration → Erroneously assigned via policy. Critical finding to report.
- Indicator of prior impairment → A previous attacker left a backdoor on a service account with this privilege.
In both cases: document, photograph, mark as a critical finding before exploiting it.
Common mistakes #
NtCreateToken → STATUS_PRIVILEGE_NOT_HELD — Privilege not enabled. Verify: whoami /priv | findstr SeCreateToken.
SYSTEM token created but Kerberos blocks access to network resources — The Kerberos PAC is signed by the DC with keys you don't control. Use the forged token for local access or NTLM authentication to network resources — it doesn't work for pure Kerberos.
Token does not take effect in the process — The forged token has not been set as primary. Use ImpersonateLoggedOnUser o SetThreadToken after creation, or use RunAs.exe -token [handle].
Token with Domain Admin SID does not access network shares — The DC is using Kerberos and validates the real PAC. Force NTLM: add host to LmCompatibilityLevel low or use tools that force NTLM.
Detection and bypass (Red Team view) #
| What the Blue Team detects | How the Red Team bypasses it |
|---|---|
Call NtCreateToken from non-SYSTEM processes | Hard to hide — works quickly and removes traces |
| ETW logging on anomalous token creation | Disable ETW consumer with SeSecurityPrivilege first |
| Non-SYSTEM account with audit privilege | This is the finding — remove it after completing the operation |
When it fails #
NtCreateToken→STATUS_PRIVILEGE_NOT_HELD→ privilege not enabled- Kerberos locks network resources → uses NTLM or PTH with real hashes
- Token not set as primary → verify
SetThreadToken/ImpersonateLoggedOnUser
Mitigations #
- Never assign SeCreateTokenPrivilege to non-system accounts
- Periodic audit:
accesschk.exe -a SeCreateTokenPrivilege * - Protected Users for privileged accounts → force Kerberos, disable NTLM fallback
- Kerberos PAC validation (default on modern AD)
Realistic note: Finding this privilege on a non-SYSTEM account is almost always a sign of a previous compromise or serious misconfiguration. In both cases, it's a P0 finding that should be reported before it's even used.
FAQ #
Why does lsass.exe have this privilege?
Must create session tokens during authentication. Each login calls NtCreateToken to construct the user's token. This is a functional requirement of the authentication process.
With the forged token, do I become Domain Admin on the network? Yes, via NTLM. No, via Kerberos—the PAC is signed by the DC and cannot be forged without KRBTGT.
Will I ever see this privilege on non-system accounts in a pentest? Rarely. If you do see it: document it, report it as P0, then exploit it.
SeCreateTokenPrivilege on a non-system account is almost certainly a prior compromise or critical misconfiguration — document before exploiting.
Related articles:
- SeTcbPrivilege — token creation via LSA instead of direct syscall
- SeImpersonatePrivilege — reactive token capture, much more common
References: token-priv PoC · Microsoft Docs








