Windows User Privileges
Last updated
Last updated
Privileges in Windows are rights that an account can be granted to perform a variety of operations on the local system such as managing services, loading drivers, shutting down the system, debugging an application, and more.
Privileges are different from access rights, which a system uses to grant or deny access to securable objects. User and group privileges are stored in a database and granted via an access token when a user logs on to a system.
Each time a user attempts to perform a privileged action, the system reviews the user's access token to see if the account has the required privileges, and if so, checks to see if they are enabled. Most privileges are disabled by default. Some can be enabled by opening an administrative cmd.exe or PowerShell console, while others can be enabled manually.
Security principals are anything that can be authenticated by the Windows operating system, including user and computer accounts, processes that run in the security context or another user/computer account, or the security groups that these accounts belong to.
Security principals are the primary way of controlling access to resources on Windows hosts. Every single security principal is identified by a unique Security Identifier (SID). When a security principal is created, it is assigned a SID which remains assigned to that principal for its lifetime.
The below diagram walks through the Windows authorization and access control process at a high level, showing, for example, the process started when a user attempts to access a securable object such as a folder on a file share. During this process, the user's access token (including their user SID, SIDs for any groups they are members of, privilege list, and other access information) is compared against Access Control Entries (ACEs) within the object's security descriptor (which contains security information about a securable object such as access rights (discussed below) granted to users or groups). Once this comparison is complete, a decision is made to either grant or deny access. This entire process happens almost instantaneously whenever a user tries to access a resource on a Windows host. As part of our enumeration and privilege escalation activities, we attempt to use and abuse access rights and leverage or insert ourselves into this authorization process to further our access towards our goal.
Windows contains many groups that grant their members powerful rights and privileges. Many of these can be abused to escalate privileges on both a standalone Windows host and within an Active Directory domain environment. Ultimately, these may be used to gain Domain Admin, local administrator, or SYSTEM privileges on a Windows workstation, server, or Domain Controller (DC). Some of these groups are listed below.
Group
Description
Default Administrators
Domain Admins and Enterprise Admins are "super" groups.
Server Operators
Members can modify services, access SMB shares, and backup files.
Backup Operators
Members are allowed to log onto DCs locally and should be considered Domain Admins. They can make shadow copies of the SAM/NTDS database, read the registry remotely, and access the file system on the DC via SMB. This group is sometimes added to the local Backup Operators group on non-DCs.
Print Operators
Members can log on to DCs locally and "trick" Windows into loading a malicious driver.
Hyper-V Administrators
If there are virtual DCs, any virtualization admins, such as members of Hyper-V Administrators, should be considered Domain Admins.
Account Operators
Members can modify non-protected accounts and groups in the domain.
Remote Desktop Users
Members are not given any useful permissions by default but are often granted additional rights such as Allow Login Through Remote Desktop Services
and can move laterally using the RDP protocol.
Remote Management Users
Members can log on to DCs with PSRemoting (This group is sometimes added to the local remote management group on non-DCs).
Group Policy Creator Owners
Members can create new GPOs but would need to be delegated additional permissions to link GPOs to a container such as a domain or OU.
Schema Admins
Members can modify the Active Directory schema structure and backdoor any to-be-created Group/GPO by adding a compromised account to the default object ACL.
DNS Admins
Depending on group membership, and other factors such as privileges assigned via domain and local Group Policy, users can have various rights assigned to their account. This Microsoft article on User Rights Assignment provides a detailed explanation of each of the user rights that can be set in Windows as well as security considerations applicable to each right.
Below are some of the key user rights assignments, which are settings applied to the localhost. These rights allow users to perform tasks on the system such as logon locally or remotely, access the host from the network, shut down the server, etc.
Setting Name
Standard Assignment
Description
SeNetworkLogonRight
Administrators, Authenticated Users
Determines which users can connect to the device from the network. This is required by network protocols such as SMB, NetBIOS, CIFS, and COM+.
SeRemoteInteractiveLogonRight
Administrators, Remote Desktop Users
This policy setting determines which users or groups can access the login screen of a remote device through a Remote Desktop Services connection. A user can establish a Remote Desktop Services connection to a particular server but not be able to log on to the console of that same server.
SeBackupPrivilege
Administrators
This user right determines which users can bypass file and directory, registry, and other persistent object permissions for the purposes of backing up the system.
SeSecurityPrivilege
Administrators
This policy setting determines which users can specify object access audit options for individual resources such as files, Active Directory objects, and registry keys. These objects specify their system access control lists (SACL). A user assigned this user right can also view and clear the Security log in Event Viewer.
SeTakeOwnershipPrivilege
Administrators
This policy setting determines which users can take ownership of any securable object in the device, including Active Directory objects, NTFS files and folders, printers, registry keys, services, processes, and threads.
SeDebugPrivilege
Administrators
This policy setting determines which users can attach to or open any process, even a process they do not own. Developers who are debugging their applications do not need this user right. Developers who are debugging new system components need this user right. This user right provides access to sensitive and critical operating system components.
SeImpersonatePrivilege
Administrators, Local Service, Network Service, Service
This policy setting determines which programs are allowed to impersonate a user or another specified account and act on behalf of the user.
SeLoadDriverPrivilege
Administrators
This policy setting determines which users can dynamically load and unload device drivers. This user right is not required if a signed driver for the new hardware already exists in the driver.cab file on the device. Device drivers run as highly privileged code.
SeRestorePrivilege
Administrators
This security setting determines which users can bypass file, directory, registry, and other persistent object permissions when they restore backed up files and directories. It determines which users can set valid security principals as the owner of an object.
Further information can be found here.
Typing the command whoami /priv
will give you a listing of all user rights assigned to your current user. Some rights are only available to administrative users and can only be listed/leveraged when running an elevated cmd or PowerShell session.
These concepts of elevated rights and User Account Control (UAC) are security features introduced with Windows Vista to default to restricting applications from running with full permissions unless necessary.
If we compare and contrast the rights available to us as an admin in a non-elevated console vs. an elevated console, we will see that they differ drastically.
When a privilege is listed for our account in the Disabled
state, it means that our account has the specific privilege assigned. Still, it cannot be used in an access token to perform the associated actions until it is enabled.
Windows does not provide a built-in command or PowerShell cmdlet to enable privileges, so we need some scripting to help us out. We will see ways to abuse various privileges throughout this module and various ways to enable specific privileges within our current process. One example is this PowerShell script which can be used to enable certain privileges, or this script which can be used to adjust token privileges.
A standard user, in contrast, has drastically fewer rights.
User rights increase based on the groups they are placed in or their assigned privileges.
This post is worth a read for more information on Windows privileges as well as detecting and preventing abuse, specifically by logging event 4672: Special privileges assigned to new logon which will generate an event if certain sensitive privileges are assigned to a new logon session. This can be fine-tuned in many ways, such as by monitoring privileges that should never be assigned or those that should only ever be assigned to specific accounts.
In Windows, every process has a token that has information about the account that is running it. These tokens are not considered secure resources, as they are just locations within memory that could be brute-forced by users that cannot read memory. To utilize the token, the SeImpersonate
privilege is needed. It is only given to administrative accounts, and in most cases, can be removed during system hardening. An example of using this token would be CreateProcessWithTokenW.
Legitimate programs may utilize another process's token to escalate from Administrator to Local System, which has additional privileges. Processes generally do this by making a call to the WinLogon process to get a SYSTEM token, then executing itself with that token placing it within the SYSTEM space. Attackers often abuse this privilege in the "Potato style" privescs - where a service account can SeImpersonate
, but not obtain full SYSTEM level privileges. Essentially, the Potato attack tricks a process running as SYSTEM to connect to their process, which hands over the token to be used.
We will often run into this privilege after gaining remote code execution via an application that runs in the context of a service account (for example, uploading a web shell to an ASP.NET web application, achieving remote code execution through a Jenkins installation, or by executing commands through MSSQL queries). Whenever we gain access in this way, we should immediately check for this privilege as its presence often offers a quick and easy route to elevated privileges. This paper is worth reading for further details on token impersonation attacks.
In this scenario, the SQL Service service account is running in the context of the default mssqlserver
account. Imagine we have achieved command execution as this user using xp_cmdshell
using a set of credentials obtained in a logins.sql
file on a file share using the Snaffler
tool.
Connecting with MSSQLClient.py
Enabling xp_cmdshell
Confirming Access
Checking Account Privileges
The command whoami /priv
confirms that SeImpersonatePrivilege is listed. This privilege can be used to impersonate a privileged account such as NT AUTHORITY\SYSTEM
. JuicyPotato can be used to exploit the SeImpersonate
or SeAssignPrimaryToken
privileges via DCOM/NTLM reflection abuse.
To escalate privileges using these rights, let's first download the JuicyPotato.exe
binary and upload this and nc.exe
to the target server. Next, stand up a Netcat listener on port 8443, and execute the command below where -l
is the COM server listening port, -p
is the program to launch (cmd.exe), -a
is the argument passed to cmd.exe, and -t
is the createprocess
call. Below, we are telling the tool to try both the CreateProcessWithTokenW and CreateProcessAsUser functions, which need SeImpersonate
or SeAssignPrimaryToken
privileges respectively.
Catching SYSTEM Shell
JuicyPotato doesn't work on Windows Server 2019 and Windows 10 build 1809 onwards. However, PrintSpoofer and RoguePotato can be used to leverage the same privileges and gain NT AUTHORITY\SYSTEM
level access.
This blog post goes in-depth on the PrintSpoofer
tool, which can be used to abuse impersonation privileges on Windows 10 and Server 2019 hosts where JuicyPotato no longer works.
Let's try this out using the PrintSpoofer
tool. We can use the tool to spawn a SYSTEM process in your current console and interact with it, spawn a SYSTEM process on a desktop (if logged on locally or via RDP), or catch a reverse shell - which we will do in our example. Again, connect with mssqlclient.py
and use the tool with the -c
argument to execute a command. Here, using nc.exe
to spawn a reverse shell (with a Netcat listener waiting on our attack box on port 8443).
Escalating privileges by leveraging SeImpersonate
is very common. It is essential to be familiar with the various methods available to us depending on the target host OS version and level.
To run a particular application or service or assist with troubleshooting, a user might be assigned the SeDebugPrivilege instead of adding the account into the administrators group. This privilege can be assigned via local or domain group policy, under Computer Settings > Windows Settings > Security Settings
. By default, only administrators are granted this privilege as it can be used to capture sensitive information from system memory, or access/modify kernel and application structures.
This right may be assigned to developers who need to debug new system components as part of their day-to-day job. This user right should be given out sparingly because any account that is assigned it will have access to critical operating system components.
During an internal penetration test, it is often helpful to use websites such as LinkedIn to gather information about potential users to target. Suppose we are, for example, retrieving many NTLMv2 password hashes using Responder
or Inveigh
. In that case, we may want to focus our password hash cracking efforts on possible high-value accounts, such as developers who are more likely to have these types of privileges assigned to their accounts.
A user may not be a local admin on a host but have rights that we cannot enumerate remotely using a tool such as BloodHound. This would be worth checking in an environment where we obtain credentials for several users and have RDP access to one or more hosts but no additional privileges.
After logging on as a user assigned the Debug programs
right and opening an elevated shell, we see SeDebugPrivilege
is listed.
We can use ProcDump from the SysInternals suite to leverage this privilege and dump process memory. A good candidate is the Local Security Authority Subsystem Service (LSASS) process, which stores user credentials after a user logs on to a system.
This is successful, and we can load this in Mimikatz
using the sekurlsa::minidump
command. After issuing the sekurlsa::logonPasswords
commands, we gain the NTLM hash of the local administrator account logged on locally. We can use this to perform a pass-the-hash attack to move laterally if the same local administrator password is used on one or multiple additional systems (common in large organizations).
It is always a good idea to type "log" before running any commands in "Mimikatz" this way all command output will put output to a ".txt" file. This is especially useful when dumping credentials from a server which may have many sets of credentials in memory.
Suppose we are unable to load tools on the target for whatever reason but have RDP access. In that case, we can take a manual memory dump of the LSASS
process via the Task Manager by browsing to the Details
tab, choosing the LSASS
process, and selecting Create dump file
. After downloading this file back to our attack system, we can process it using Mimikatz the same way as the previous example.
We can also leverage SeDebugPrivilege
for RCE. Using this technique, we can elevate our privileges to SYSTEM by launching a child process and using the elevated rights granted to our account via SeDebugPrivilege
to alter normal system behavior to inherit the token of a parent process and impersonate it.
If we target a parent process running as SYSTEM (specifying the Process ID (or PID) of the target process or running program), then we can elevate our rights quickly. Let's see this in action.
First, transfer this PoC script over to the target system. Next we just load the script and run it with the following syntax [MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>,"")
. Note that we must add a third blank argument ""
at the end for the PoC to work properly.
The PoC script has received an update. Please visit its GitHub repository and review its usage. https://github.com/decoder-it/psgetsystem
First, open an elevated PowerShell console (right-click, run as admin, and type in the credentials for the jordan
user). Next, type tasklist
to get a listing of running processes and accompanying PIDs.
Here we can target winlogon.exe
running under PID 612, which we know runs as SYSTEM on Windows hosts.
We could also use the Get-Process cmdlet to grab the PID of a well-known process that runs as SYSTEM (such as LSASS) and pass the PID directly to the script, cutting down on the number of steps required.
Other tools such as this one exist to pop a SYSTEM shell when we have SeDebugPrivilege
. Often we will not have RDP access to a host, so we'll have to modify our PoCs to either return a reverse shell to our attack host as SYSTEM or another command, such as adding an admin user.
SeTakeOwnershipPrivilege grants a user the ability to take ownership of any "securable object," meaning Active Directory objects, NTFS files/folders, printers, registry keys, services, and processes.
This privilege assigns WRITE_OWNER rights over an object, meaning the user can change the owner within the object's security descriptor. Administrators are assigned this privilege by default. While it is rare to encounter a standard user account with this privilege, we may encounter a service account that, for example, is tasked with running backup jobs and VSS snapshots assigned this privilege. It may also be assigned a few others such as SeBackupPrivilege
, SeRestorePrivilege
, and SeSecurityPrivilege
to control this account's privileges at a more granular level and not granting the account full local admin rights.
These privileges on their own could likely be used to escalate privileges. Still, there may be times when we need to take ownership of specific files because other methods are blocked, or otherwise, do not work as expected.
Abusing this privilege is a bit of an edge case. Still, it is worth understanding in-depth, especially since we may also find ourselves in a scenario in an Active Directory environment where we can assign this right to a specific user that we can control and leverage it to read a sensitive file on a file share.
The setting can be set in Group Policy under:
Computer Configuration
⇾ Windows Settings
⇾ Security Settings
⇾ Local Policies
⇾ User Rights Assignment
With this privilege, a user could take ownership of any file or object and make changes that could involve access to sensitive data, Remote Code Execution
(RCE
) or Denial-of-Service
(DOS).
Suppose we encounter a user with this privilege or assign it to them through an attack such as GPO abuse using SharpGPOAbuse. In that case, we could use this privilege to potentially take control of a shared folder or sensitive files such as a document containing passwords or an SSH key.
Let's review our current user's privileges.
Notice from the output that the privilege is not enabled. We can enable it using this script which is detailed in this blog post, as well as this one which builds on the initial concept.
Next, choose a target file and confirm the current ownership. For our purposes, we'll target an interesting file found on a file share. It is common to encounter file shares with Public
and Private
directories with subdirectories set up by department.
Given that our user account has SeTakeOwnershipPrivilege
(which may have already been granted), or we exploit some other misconfiguration such as an overly permissive Group Policy Object (GPO) to grant our user account that privilege) we can leverage it to read any file of our choosing.
Take great care when performing a potentially destructive action like changing file ownership, as it could cause an application to stop working or disrupt user(s) of the target object. Changing the ownership of an important file, such as a live web.config file, is not something we would do without consent from our client first. Furthermore, changing ownership of a file buried down several subdirectories (while changing each subdirectory permission on the way down) may be difficult to revert and should be avoided.
Let's check out our target file to gather a bit more information about it.
We can see that the owner is not shown, meaning that we likely do not have enough permissions over the object to view those details. We can back up a bit and check out the owner of the IT directory.
We can see that the IT share appears to be owned by a service account and does contain a file cred.txt
with some data inside it.
Now we can use the takeown Windows binary to change ownership of the file.
We may still not be able to read the file and need to modify the file ACL using icacls
to be able to read it.
Let's grant our user full privileges over the target file.
After performing these changes, we would want to make every effort to revert the permissions/file ownership. If we cannot for some reason, we should alert our client and carefully document the modifications in an appendix of our report deliverable. Again, leveraging this permission can be considered a destructive action and should be done with great care
Files of Interest
Some local files of interest may include:
We may also come across .kdbx
KeePass database files, OneNote notebooks, files such as passwords.*
, pass.*
, creds.*
, scripts, other configuration files, virtual hard drive files, and more that we can target to extract sensitive information from to elevate our privileges and further our access.
Members can load a DLL on a DC, but do not have the necessary permissions to restart the DNS server. They can load a malicious DLL and wait for a reboot as a persistence mechanism. Loading a DLL will often result in the service crashing. A more reliable way to exploit this group is to .
Setting