[Author's Note: This is the 4th in a multi-part series on the topic of "Protecting Privileged Domain Accounts". My primary goal is to help incident responders protect their privileged accounts when interacting with comprised hosts, though I also believe this information will be useful to anyone administering and defending a Windows environment.]
I've previously written about the risks of exposing password hashes on a compromised machine. It turns out that there is another way to take advantage of authentication credentials on a Windows host that is very similar to stealing password hashes and using them in pass-the-hash attacks. This method takes advantage of Windows access tokens, which are somewhat similar in concept to non-persistent web cookies. They reside in memory and are essentially used for single-sign on functionality, allowing a user's security attributes, including user privileges and group memberships, to be easily referenced by any process or thread associated with the user.
With that quick description, it should be obvious that the token of a privileged user could be of great use to an attacker. So as part of our goal of protecting privileged domain accounts, we need to take a look at this issue.
What Are Access Tokens?
In Windows versions prior to Vista, there are 2 types of tokens, as described by Microsoft (Vista and higher also utilize a "filtered" token for User Account Control, which is essentially a primary token with administrative rights removed):
"...there are two kinds of access tokens, primary and impersonation. Every process has a primary token that describes the security context of the user account associated with the process. A primary access token is typically assigned to a process to represent the default security information for that process. Impersonation access tokens, on the other hand, are usually used for client/server scenarios. Impersonation tokens enable a thread to execute in a security context that differs from the security context of the process that owns the thread."
The impersonation token is where it gets interesting from our standpoint, since it is used in a client-server scenario. This implies that we need to take care of impersonation tokens of privileged users when connecting to remote servers--and by "servers", I mean server services, which apply to both Windows workstations and full-fledged Windows servers.
To give an example of how impersonation can be used, consider a Microsoft FTP server that you connect to with an authorized account. That authorized account likely has rights to upload and download files from certain directories, but not others. The way that the FTP server knows your rights is by impersonation. When the FTP server process is tasked with servicing your requests, the process briefly runs under your impersonation token so that it knows inherently what your privileges are--i.e., what files and folders you have access to. Once it's done servicing your request, it goes back to doing its work with its primary token, or with another user's impersonation token.
There are four impersonation levels: anonymous, identify, impersonate, and delegate. This TechNet blog does a nice job of describing these four levels:
"These levels refer to what you can do with the impersonation token after you get it. Anonymous is just like it sounds — we can impersonate you as an anonymous user and that's all. Identification is when a process can pull your token to validate credentials, but cannot do anything with the token. Impersonation means that the process can perform tasks as a different user... Impersonation is limited only to tasks local to that computer... A process cannot 'run a task' or 'request an object' that resides outside of the system... Delegation is one step beyond Impersonation, where the process can call resources and perform tasks on other computers than it. ...[Delegation] is a feature provided to us by the Kerberos authentication protocol and also referred to as 'double hop' authentication — meaning that our credentials hop from one computer to the next, rather than us having to go to each computer individually."
In practice, the impersonate-level and delegate-level tokens are of interest from an attacker's standpoint, since they are the ones that allow code to be run under a different user's security context.
When Do These Tokens Show Up?
Impersonate-level tokens are present from remote network logons, such as SMB connections. In the case of SMB, the SMB server is impersonating the privileges of the remote user, which gives the server the ability to access files and services provided by that remote user's security context.
Delegate-level tokens are present from interactive logons, which include console logons, RunAs, PsExec with the "-u" option, and RDP/VNC-style remote desktop logons. I've previously discussed the significant risk from interactive logons exposing password hashes, so we should definitely avoid this logon type with our privileged domain accounts.
Delegate-level tokens can also be present from network logons to certain services, such as SharePoint. SharePoint, which often utilizes a web server front-end and a SQL Server back-end, is a perfect example of how delegation can be useful. It allows a client to connect and authenticate to the front-end web server and then the web server connect to the SQL Server as the authenticated client. The back-end SQL Server can then impersonate the client so that it knows what data should be available to the client. This type of multi-tier solution is a common scenario where you will find delegation in use. Also note that Microsoft's Encrypting File System (EFS) utilizes delegation for encrypting and decrypting files on behalf of the user.
In order to support the delegation feature, Windows requires that either the computer account hosting the service, or a domain user account configured to run the service, must be trusted for delegation in Active Directory.
Here's a screenshot showing where delegation can be enabled in Active Directory for a specific user account:
And here's a screenshot showing how delegation can be enabled in Active Directory for a specific computer account (the pop-up appeared once I checked "Trust computer for delegation"):
For the testing purposes, I've left this setting enabled on the computer account for the compromised host USER-XP-PC. It would be unusual and not recommended for delegation to be enabled for a standard workstation account, but I'm allowing it here for demonstration purposes.
Token Stealing Requirements
So that's what must occur for the impersonate-level and delegate-level tokens to be created and available for use, but what has to occur to actually acquire and use them? The attacker's code must be running as a user with the impersonation privilege (SeImpersonatePrivilege). By default in Windows XP, Administrators have this right, as do members of the built-in SERVICE group, as shown here:
Typically the attacker will have already elevated to Adminstrator/SYSTEM rights, so this is rarely an issue.
Token Stealing in Action
So now let's look at an example of token stealing and then show you a way to mitigate the most severe aspect of this threat--stealing the delegate-level token. In this testing, I'm using the same scenario and test machines as described in my post on safeguarding password hashes.
I will focus specifically on stealing the delegate-level token. While it is certainly possible to steal an impersonate-level token and use it for local privilege escalation, that's not really a concern in my scenario because I'm assuming the attacker already has full control of the compromised host. I'm also assuming that an administrative account must be used to effectively analyze the host, and as such, any administrative account will be vulnerable to stealing the (local-use only) impersonate-level token in the same manner. What I particularly want to protect is the delegate-level token, which if available, would allow an attacker to authenticate to remote machines as the privileged domain account.
The tool I'm going to use for viewing and stealing access tokens is Luke Jennings' incognito tool. More specifically, I'm going to use the Metasploit incognito module for these tests (also authored by Mr. Jennings) because I've found that it's a little more consistent than the incognito standalone executable. Mr. Jennings' paper titled "Security Implications of Windows Access Tokens — A Penetration Tester's Guide" is a terrific resource for understanding this issue, as well as describing how his tool works.
In our scenario, we have a potentially compromised Windows XP SP2 machine named "USER-XP-PC". We have an incident responder named "MSAD2-RESPONDER1" that needs to connect to the machine for analysis from his machine "IR-XP-PC". I tested NET USE, WMIC, and PsExec in my previous article. For this article, I will focus only on PsExec because it was the only one of the three that I found to be vulnerable to delegate-level token stealing by default, assuming the compromised computer is trusted for delegation. For WMIC, it is possible to enable delegation by specifying the /IMPLEVEL switch.
So let's get started!
- Here we have our responder connecting with PsExec from his machine, IR-XP-PC, to the remote compromised machine, USER-XP-PC:
- The attacker has caused a Metasploit Meterpreter session to be initiated on the compromised machine, USER-XP-PC. At this point, the attacker has full remote control of USER-XP-PC from the Metasploit console of his BackTrack Linux machine. Here we see the attacker's attempt to steal MSAD2-RESPONDER1's delegate-level token:
- Now that the attacker is running as MSAD2-RESPONDER1, let's see what he can do. Picking up from the same session:
The results above show a very effective method for elevating credentials from a standard domain account to a privileged domain account (a domain admin in this case) and gaining access to a domain controller's backup file. Domain controller backup files often contain the NTDS.DIT and Registry files necessary to extract domain hashes, as detailed in Csaba Barta's paper "Active Directory Offline Hash Dump and Forensic Analysis". A more realistic scenario (and perhaps an easier one too) might be for the attacker to go after the files on a backup server using a backup administrator's account. In any case, we see that the impact of stolen delegate-level tokens of a privileged domain account can be quite severe.
Protect Your Tokens
Now let's see what we can do to mitigate this issue. Fortunately, Microsoft provides us with an easy and effective way to protect our privileged accounts. For your IR and most any other privileged domain accounts, you should enable the checkbox "Account is sensitive and cannot be delegated" within the accounts' properties:
Microsoft recommends this as a best practice for securing sensitive accounts, as described in this TechNet article on delegation. Keep in mind that this is probably not a feature you want to enable on your standard domain account if you use multi-tier applications like SharePoint, for the reasons discussed above. However, for IR accounts, domain admin accounts, and other highly-privileged accounts, there should be no adverse side effects from enabling this setting because it's very unlikely you will need to access these multi-tier applications with these accounts. Keep in mind, however, that remote EFS operations require delegation.
Let's test this out and see if it works as expected. After applying the setting above to MSAD2-RESPONDER1 and rebooting my test machines, here's what happens.
- Once again, here is our responder connecting with PsExec from his machine, IR-XP-PC, to the remote compromised machine, USER-XP-PC:
- Again, the attacker initiates a Metasploit Meterpreter session in order to gain control of the compromised machine. All of the following commands are run on the compromised host, USER-XP-PC, from the attacker's BackTrack Linux machine:
- Everything looks the same as before, but let's see if we can actually connect to the domain controller as we were able to do when the "Account is sensitive and cannot be delegated" setting was left unchecked:
- It failed! So what happened? Let's look at the logs on the domain controller, MSAD2-DC-2K3:
We see the network logon attempt (Event ID 540) at 7:11:31 PM from workstation USER-XP-PC. It's actually a successful network logon, but as ANONYMOUS--not as MSAD2-RESPONDER1. This is because without the delegate-level token, connections to remote workstations are devoid of their credentials and therefore become ANONYMOUS logons--which although authenticated, was not authorized by the DC. So in other words, it failed as we would expect.
This is an important result for us. Enabling the setting "Account is sensitive and cannot be delegated" means we can prevent our privileged accounts from allowing the delegate-level token to be available to the attacker. Otherwise, there is a distinct possibility that attackers could steal a responder's delegate-level token to move laterally throughout the network, which can be every bit as devastating as compromised hashes of the privileged account.
Although this setting has disabled the ability to steal a delegate-level token, an impersonate-level token will still be available to an attacker. As mentioned earlier, this does open up a local privilege escalation vulnerability on the compromised machine. In our scenario though, we're less concerned with this because most likely the machine is already fully compromised by the attacker, and even if it's not yet fully compromised, we've established that we need administrative rights to effectively analyze the machine. Since any administrative account (local or domain) is vulnerable in the same way for local-only privilege escalation, there's no additional risk with using a domain account instead of a local admin account.
On the other hand, in scenarios where you are not be willing to take the chance of local privilege escalation, your IR process will warrant offline analysis rather than live analysis via the network.
Mike Pilkington is a Sr. Information Security Analyst and Incident Responder for a Fortune 500 company in Houston, TX, as well as a SANS Mentor and Community Instructor.