SeTcbPrivilege to SYSTEM, then a new local admin

  • windows
  • privilege-escalation
  • tokens

Proof of concept on GitHub

If a process already holds SeTcbPrivilege, the act as part of the operating system right, it can turn that one privilege into a brand new local administrator account without ever knowing a password. This post explains the mechanism, where it is useful, and how a defender would catch it.

The assumption it abuses

Windows trusts a process that holds SeTcbPrivilege to speak for the operating system. Concretely, such a process can acquire an SSPI credential handle bound to a logon session other than its own, including the built in SYSTEM session, whose well known LUID is 0x3E7. A normal caller may only name its own logon session. A caller holding SeTcbPrivilege may name SYSTEM. Nothing is corrupted or overflowed. A granted privilege is used exactly as designed, by a context that should never have held it.

Reaching SYSTEM through a service

With a SYSTEM backed credential handle, the process opens the Service Control Manager over an authenticated channel, so the SCM sees the connection as SYSTEM. It then creates a service. A service created without an explicit account runs as LocalSystem, so the service command executes as SYSTEM. Starting it fails the usual handshake with error 1053, the service did not respond in time, because the command is not a real service. That is expected and does not mean the payload failed.

Minting the administrator

Running as SYSTEM, the service command creates an account and adds it to the local Administrators group. The service is then deleted, but the account remains. Cleaning up the delivery mechanism is not cleaning up the result.

Where to use it

This is a local privilege escalation primitive, useful once you have code execution in a context that already holds SeTcbPrivilege, for example a service account or a scripting console hosted by such a service. It is not a remote exploit and not a way to obtain SeTcbPrivilege in the first place. Confirm the privilege is present and enabled before relying on it.

A common delivery surface for that code execution is the Liferay Groovy script console, and this primitive is the final link of the full application-admin to SYSTEM chain. The token privilege it abuses sits alongside the other Windows local privilege-escalation hops.

Detection and defense in brief

The chain is loud. A transient service install (System log 7045) followed closely by a new account (Security 4720) and a member added to Administrators (4732), under the SYSTEM account, is the signature. The proportionate fix is to review and reduce which accounts and services hold SeTcbPrivilege, since removing the precondition removes the whole chain. The application-admin to SYSTEM chain post expands this same signature with the privilege-use events (4672/4673) and correlation.

Proof of concept

The working code, build instructions, and a staging note are in the GitHub repository linked below.

Use

Authorized and educational use only: your own systems, a lab you control, or an engagement with written permission. This explains the mechanism so defenders can detect and remove it (strip SeTcbPrivilege from accounts that do not need it), not for use against systems you do not own.

Proof of concept on GitHub

Back to all techniques