Tuesday, October 16, 2018

Forging Trusts for Deception in Active Directory

Deception has always been of interest to me. As a student of military history, I have always been fascinated by its implementation in warfare and looked at deception as something which is effective and generally low cost!
Couple of years back, I got involved in development and extensive testing (from red team perspective) of couple of enterprise deception solutions over a period of many months. In early 2018, during one of my Active Directory classes, a student  asked and ultimately hired me (thank you!) for testing three Deception products they were evaluating. 

With these experiences I realized that most of the focus for deception in Active Directory (AD) has been on honeyuser/honeytokens/honeycredentials. Tools like dcept and others are popular for this technique. There is a dearth of free and open source deception solutions for AD if we want to utilize deception to detect an adversary during the domain enumeration phase of an attack. That is something which we are going to address soon.

Also, to increase interest and community involvement, I gave a talk on 'Forging Trusts for Deception in Active Directory' at BruCON couple of weeks back (October 2018). Slides and video are at the end of this post.

What is Deception?


Deception is a psychology game. Red teams and adversaries have been using it for so long against unsuspecting users to trick them in opening malicious attachments or clicking on links. Once inside an AD environment, an adversary tries to use credentials of other users and pivot through other machines to mix with the existing logs and traffic.

Blue teams utilize deception by providing service, privileges or information can adversary is looking for. IMHO, blue teams, have an upper hand when it comes to deception, both in terms of psychology and technical controls.

The attacker psychology 

There is a psychological condition called Illusive Superiority which applies to most of the adversaries and red teams. They think of themselves as smarter and much more talented than the blue teams. Along with this, the tendency to go for the "lowest hanging fruit" and an urge for getting DA privileges quickly, makes them a fruitful target for deception :)

So, the idea is, defenders show the adversaries what they want to see. For example, a user whose password never expires or a Server 2003 computer.

Desired properties of a decoy

Taken directly from my slides, desired properties of a decoy:
  1. Should be desirable enough so that an attacker enumerates the object.
  2. Should be easily configurable.
  3. No configuration changes required on endpoints.
  4. Should not be triggered for normal admin activity.
Number 4 above is the hardest to achieve. If we are targeting enumeration, we must make the attacker activity or tools stand-out to avoid false positives.

Deploying Deception

So, how can we achieve above desired properties with just the built-in tools in AD? We can use Group Policy to set AD Access logging, configure 'interesting' objects and filter out false positives!

The Group Policy setting required for AD Access is Windows Settings | Security Settings | Advanced Audit Policy Configuration | DS Access - Audit Directory Service Access
AD Access Group Policy
Above setting results in a Security Event 4662 whenever an AD object is accessed. The logging needs to configured at the object level. For that configuration, we need to modify the SACL of the object and add relevant ACEs.

Let's have a look at the AddAuditAccessObjectAce function to understand ACE:

So, as an example, we can set auditing whenever 'everyone' uses 'ReadProperty' 'success'-fully against a user. This helps in detecting any enumeration against that user.

Introducing Deploy-Deception

These settings can be done using GUI. But thanks to PowerShell and the ActiveDirectory module, it can be automated.

To automate the setting up of decoy object with interesting attributes and lesser known properties to avoid false positives , I wrote Deploy-Deception. It is a PowerShell module which utilizes the ActiveDirectory module to deploy decoys easily and efficiently. You can find Deploy-Deception on Github here: https://github.com/samratashok/Deploy-Deception


Let's have a look at setting up of different types of object decoys during different phases of an attack.

Enumeration - Decoy User Objects

User objects are the most interesting objects  Some user properties are of interest for an attacker:
  • Password does not expire
  • Trusted for Delegation
  • Users with SPN
  • Password in description
  • Users who are members of high privilege groups
  • Users with ACL rights over other users, groups or containers
We can use Deplou-UserDeception function to create a decoy user.
Let's create a decoy user 'usermanager' whose password never expires and a 4662 is logged whenever everyone reads any of its properties:

Please note that an actual user objects is created in the domain. Now, the above gets triggered very frequently as we have enabled the default logging for whenever anyone reads any property of the user usermanager. It means a 4662 will be logged even if someone simply lists all the users in the domain. This means, that this decoy will trigger logging for all the possible usage (normal or otherwise) like

net user /domain

Get-WmiObject -Class Win32_UserAccount

Get-ADUser -Filter * (MS ActiveDirectory module)

Get-NetUser (PowerView)

Find Users, Contacts and Groups GUI

That does not look good, right? So we need to find ways to differentiate attacker enumeration from normal activity. There is something very interesting with attacker enumeration tools, they like to extract as much information for an object as possible (which makes sense as you would not like to connect repeatedly to a domain controller). Now, this means that if we turn on auditing for an uncommon attribute, there is a large possibility (yes, possibility - share your false positives with me please :P) that only aggressive enumeration triggers the logging. There are many such attributes, have a look at the List of All Attributes. I liked once such attribute - x500uniqueIdentifier (GUID d07da11f-8a3d-42b6-b0aa-76c962be719a)

So, we now remove the ACE we added previously and add a new one which triggers logging only when x500uniqueIdentifier property is read:
This auditing is triggered only by tools like PowerView (or other tools like ADExplorer) which fetches all the attributes of an object. While not perfect, this is a huge improvement.

If you have enough confidence that none of your monitoring or management tools read all the properties of a user object, auditing for properties like SPN can also be set which triggers logging only when SPN (or all attributes) is read.
Still too many logs? The below command logs a 4662 log only when DACL (or all attributes) of the decoy user object is read:

Enumeration - Decoy Computer Objects

We can also set decoy computer objects. It is possible to create computer objects in domain without having an actual computer mapped to that object. Although, it is always advised to use actual computers or VM for decoy computer objects to avoid identification of decoys.

Some computer object properties which are of interest to an adversary:
  • Older Operating Systems
  • Interesting SPN
  • Delegation Settings
  • Membership of privileged groups
Let's have a look at some deployment using Deploy-Deception, we can use Deploy-DecoyComputer function. :
Above command creates a decoy computer that has Unconstrained Delegation enabled and a 4662 is logged whenever x500uniqueIdentifier or all the attributes of the computer are read.
Above command uses an existing computer object and sets Unconstrained Delegation. Logging is triggered whenever DACL or all the attributes of the computer are read.

We can also use DCShadow to modify a computer object which appears to be a DC. I briefly touched on this here. More on this particular topic some other day.

Enumeration - Decoy Group Objects

We can also deploy decoy Group objects. What properties of a group are interesting to an adversary?
  • Interesting name (containing words like admins, administrators etc.)
  • Members of the group are also member of high privileged groups or have 'interesting' user attributes. 
  • Membership of a high privilege group.

Groups provide interesting opportunities. We can make decoy users member of a decoy group thus creating 'layered' decoys. This way we get logs both when membership of the decoy group is listed and when attributes of the decoy user are listed. We will see soon how to use Logon restrictions to avoid mis-use of privileges of a user.

So in the below command, we create a decoy user 'dnsmanager' whose password never expires with logging when an obscure property is read, create a group with name 'Forest Admins', make dnsmanager part of the forest admins group and add the forest admins group to the built-in dnsadmins group. Logging is triggered when membership of the group is read. We can use Deploy-GroupDeception for this:

Enumeration and Lateral Movement - Privileged Decoy User Objects

We can also deploy high privilege user decoys to target both enumeration and lateral movement. We can create decoy users which have high privileges like membership of domain admins, rights to execute DCSync etc.

Now, the risk with having decoy users with such high privileges is if such a user gets compromised, its privileges can be abused. To avoid that,  we can use couple of protections:
  • Set the Logon Workstation to a non-existent machine
  • Deny logon to the user.
In both the above cases, AFAIK, user privileges cannot be used as the decoy user cannot logon to any box with any type of credential like password, hash etc.

Armed with this knowledge, let's create high privilege user decoys using Deploy-PrivilegedUserDeception :
The above command creates a user called 'decda' who is a part of the Domain Admins but cannot logon to any machine. Any attempt to list DACL of the user or list all attributes results in a 4662 log.

For the lateral movement part, we have used the DenyLogon protection. That means even if the user's password or hash or keys are compromised, it will not be possible to reuse those credentials. To get meaningful logs when credentials of such a user are used, we must enable the following Group Policy:
Configuration|Windows Settings|Security Settings|Advanced Audit Policy Configuration|Audit Policies|Account Logon | Audit Kerberos Authentication Service | Failure
This is how the failure looks like in GUI.
And a 4768 (Failure) is logged on the Domain Controller. In case of attacks like OverPass-The-Hash no such verbose error is returned.

Another option is to set LogonWorkstation to a nonexistent machine. It always makes sense to use a name similar for the workstation that is similar to your actual machines.
Above command creates a decoy user call 'decda', provides it with DCSync permissions and sets the LogonWorkStation to a non-existent machine. If the users credentials are compromised and re-used the error would exactly be the same as in case of DenyLogon and a 4768 is logged.

Both the protections can be used with a non-DA account as well. IMHO, this is better than leaving wrong passwords or hashes in memory (which is a well known technique).

This technique can always be coupled with others. For example,when targeting lateral movement, one of the easier ways to let an adversary 'retrieve' credentials for a decoy user is to use the -PasswordInDescription option of Deploy-UserDeception. Then, we can make that user a privileged user and use one of the protections discussed above:
The first command above creates a newuser called 'newda', sets the string 'The new password is Pass@123' as its description. The second command makes newda a member of the domain admins group, denies logon to the user and configures auditing whenever DACL or all attributes of newda are read.

No special tools are required to get the password from description! Remember targeting 'go for the lowest hanging fruit' ;)

While discussing users with privileges, there is another important aspect that must be discussed. It is about ACLs. A user which have interesting permissions over another user is always of interest to an attacker. (Side note: Make sure that you ACL auditing is a part of your security methodology - both for domain objects and other securables).

We can use Deploy-SlaveDeception to deploy decoy users where one of the users have FullControl/GenericAll rights over other user. This is interesting for an attacker and can be used to target both enumeration and lateral movement phase.

To target enumeration, following can be used:
The first and second command above, create users masteruser and slaveuser respectively and set auditing only when an obscure attribute is read. The third command provides masteruser GenericAll rights over slaveuser. Any adversary enumerating or scanning interesting ACLs in your domain will trigger 4662 for both the objects.


To target lateral movement, we can use PasswordInDescription option for masteruser or leave its credentials using other popular methods without any protection. We are ready to risk masteruser to be compromised and used (Please carefully consider risks before doing that). If masteruser modifies DACL of slaveuser we get a 4662 log in addition to any other alerts that are triggered whenever a honeytoken/honeyuser is used:
In the above command, a 4662 is logged only when masteruser changes DACL of slaveuser.

Enumeration - Domain and Forest Trust objects

Yet to be automated! There are many interesting possibilities though! For example, we can have a decoy forest trust (let's call it blue forest :P) where we can allow enumeration of users, computers and groups but deny access to any other resource. This can be achieved by setting up a forest trust with Selective Authentication where "Allowed to Authenticate" is set only on the DC but no other machine. This will allow an adversary to enumerate objects but they cannot access resources on other computers.

Red Team Revenge - Identifying Deception

So how do red teams identify which objects are actual and which are traps or decoys? As I mentioned in the beginning of the post, I have tested multiple Deception solutions over past months. There are multiple Enterprise solutions that use objects which can be identified by looking at their attributes. Some of such attributes:

  • objectSID - This object must always have DomainSID-RID format. Some enterprise solutions mess that up. If you find an object whose SID does not contain the domain SID. Make sure you investigate that object carefully.
  • lastLogon, lastlogontimestamp - User decoys can be identified by looking at these attributes. If there is a user that too high privileged one who has never logged on (lastLogon set to 31/12/1600 which is before the 'zero' date for LargeInteger datetime), there are good chances that it is a decoy. 
  • logonCount - Although not as good as lastLogon, logonCount is also a good indicator.
  • whenCreated - Coupled with lastLogon and logonCount, this becomes a good indicator. A user which is old but has never logged-on could be a decoy. You may like to notice that it may also be a dormant user, to be sure have a look at other attributes.
  • badPwdCount,badPasswordTime - Ever seen a human user who will not fat-finger their password? A user with 0 Badpwdcount (and other bad password attributes) is a good indicator of a decoy. 
  • Too many attributes - Some enterprise solutions fill up ALL or way too many possible attributes for an object. This can also be easily spotted. 
The best way is to match an object with a well known 'good' object. For example, if you suspect that a computer object in a list of all computers in the domain is a decoy compare it with the properties of the domain controller or attributes of your own foothold machine. The actual dc is always listed in the logonserver environment variable. For user object, the built-in DA always has RID 500. Compare its attributes with a user object you suspect of being decoy.

For multiple solutions which relied on not creating actual objects in the domain, using WMI to retrieve domain information shows correct objects and not the fake ones.

Red Team Revenge - Avoiding Deception

(Taken directly from my slides) Red Teams need to change their approach and their psychology of illusive superiority to avoid deception:
  • Please stop going for the lowest hanging fruit. Enterprise networks are mess but if something looks to good to be true, investigate carefully!
  • Avoid automated enumeration tools unless you absolutely know what they are doing in the background.
  • I have been urging this in my talks (on ATA) and trainings - Avoid the urge to go for the DA privileges so that you can brag about it in the reports! Focus on goals of your operation.

Blue Teams - Avoiding identification

If actual domain objects are used chances of identification are decreased. For example, a computer object which is not mapped to an actual computer has much higher chances of getting identified.

For user decoys, as discussed earlier, having at least one logon session decreases the chances of identification. Let's test this one out.

Let's have a look at a simple example. There is a well known deception identification script called HoneypotBuster. Let's create a decoy DA and run the script:

Our decoy DA was detected. Deploy-PrivilegedUserDeception has an option 'CreateLogon'. This parameter starts and stops calculator on the DC with the decoy DA user which populates the logon related properties of the user. To use this parameter, the LogonWorkstation protection must be set to the DC where the module is being executed. You can always change the behavior of the user later.
The above command creates decda, makes it a member of the Domain Admins group, restricts logon to the DC and creates a logon session (which also creates a profile on the DC). Now, if we run Honeypot Buster
Sweet, the FakeRank or confidence of the tool is down to 50. Honeypot buster uses a ranking system for objects and if a user has a logonCount less than 6 there would always be some confidence of it being fake. If we make the logonCount to 6 for decda by starting a process with its credentials 6 times, it would not show up in this tool.
Now if we run HoneypotBuster, decda is not detected! But that would be targeting this specific tool so let's not read much into this 'bypass'. 

Future Work and Community Involvement

It would be great if you deploy the decoys in your domain environments and share the results with me. That way, even if you cannot contribute to the code, you will immensely help the project.

OU objects are just around the corner and should not take much long to be included in the tool. I am also working on automating domain and forest trust decoys.I also have super ambitious plans of using virtualization to deploy decoys forests and computers in real time!

That is all! Thank you very much for reading this rather long post. You can find slides and video of my talk at BruCON below!






No comments:

Post a Comment

Note: Only a member of this blog may post a comment.