Deception & Detection in Active Directory
Blog on how to deploy deception in AD Environment
In this blog, we will take a look at how blue teamers like us can deploy deception technologies to fool adversaries, and confuse them with fake users, groups, computers and honey credentials to waste their time and keep them away from actual objects.
In this blog, we will take a look at
What deception is
Deploying deception in AD
Code explanation
Detection and possible mitigation
What is Deception?
As per Rapid7, Deception technology is a cybersecurity defence practice that aims to deceive attackers by distributing a collection of traps and decoys across a system's infrastructure to imitate genuine assets. If an intruder triggers a decoy, then the server will log and monitor the attack vectors utilized throughout the duration of the engagement.
Modern-day deception technology defences borrow heavily from military deception principles employed by the likes of Chanakya, Sun Tzu, Napoleon, and Genghis Khan to conquer continents through deceit, camouflage, and subterfuge. In the context of cybersecurity, defenders use decoys and lure to mislead attackers into believing they have a foothold in the network and revealing themselves.
Here are some of the advantages of implementing Deception.
Improves overall threat detection.
Increases the coverage, deception can detect threats at the perimeter, on endpoints, in the network, in Active Directory, and throughout application layers, as well as cover often neglected environments like SCADA/ICS, IoT, and the cloud.
Decreases the false positives during detection.
Here is how I can define deception to you through memes ☺️
Here are the two greatest deception artist in anime fooling their opponents 😎
Now that we have an idea of what deception is, we can move on towards implementing it in AD Environments.
Environment Overview
Before implementing deception, as a blue-teamer we should first always get an overview of the environment we will be working on.
Here is the AD Environment we will be implementing our deception
The AD consist of
Domain - Chrollo.local
Domain Controller - DC01
Client machine - Client01
SPNs - SVC_SQLService, SVC_FTPService
We will be acting as an adversary that has gained credential access to one of the legitimate users on the AD. On the other hand, we will also we acting as a defender that will be keeping a eye on the logs generated by decoy objects
Deception Tool
For this demonstration, we will be using an open-source Powershell deception deployment tool called "Deploy-Deception".
This is a fantastic Powershell tool ideal for deploying deception. With Powershell, this tool becomes more flexible to work with.
Pre-condition: The ideal method is to use this tool from the domain controller so that we can have full privileges over the domain to make changes to it.
Now that everything is setup let's start
Decoy User 1
Setup
Creating a decoy domain user called "Arthur" and turning on "Generic read" for everyone which means if any user in the domain read any properties of the decoy user a log will be generated.
Here is the diagram representation to understand better.
Code Explanation
To understand better, we will take a look at the Powershell code of "Deploy-Deception.ps1".
Here is the code link for reference.
First, we will focus on the function "Create-DecoyUser" on line 15.
This function will first create a decoy user. Moving down to line 44
Lines 45 and 53 define the parameter for username and password. Then it prints the verbose output. Now coming off the if-else condition on line 65
If there is no OU defined in the if statement then it will create a user normally without specifying the OU object in the else statement on line 78.
Now that the decoy user is created. Take a look at the second half of the command that has “Deploy-UserDeception”
Now focus on lines 489 and 497.
It will take two parameters as highlighted. In "$Useflag" we will be selecting the "PasswordNeverExpires" value ahead.
On lines 533 and 538, it will check if the user already exists or not. It will use "Get-ADObjectDetails" function. The function is taking the "-SamAccountName" parameter. In the "Get-ADObjectDetails" function check the line
In the "if" statement it will get the user properties using the "Get-ADUser"
Now focusing back on the previous function. In the "If" statement.
If the parameter's value is "PasswordNeverExpires", then it will set the property using the "Set-ADAccountControl" that modifies the UAC.
Moving to line 578, Both the above “if” statements will be false because we did not set any of those parameters.
The "Set-AuditRule" function(highlighted) on line 591 will set the auditing rule for the user “Arthur” in this case. Take a look at the "Set-AuditRule" function.
On line 374, it will get the object details using the "Get-ADObjectDetails" functions we saw earlier.
On line 376, It will get the ACLs from the "Get-ADObjectDetails".
Then if the parameter "GUID" is not given in the command it will go into the "If" statement on line 379. It will create an Audit rule variable with the "DirectoryServices.ActiveDirectoryAuditRule" class
Then on line 402, it will add the audit rule.
Then on line 411, it will finally set the ACL.
Okay, that was a handful😅. Let's move on to testing the detection.
Simulation And Detection
Before we move forward towards simulation. First, we need to set the 4662 Event ID in the "Gpedit".
The 4662 Event will be generated when a user accesses an AD Object.
Now, will act as an adversary that has gained access to user "Aizen" credentials and will be performing net.exe commands on the domain user. Below is the attack diagram.
This will generate a 4662 Event ID on the Event Viewer in the Domain Controller.
The Event was successfully generated. If we check the details.
This shows that the user "Aizen" was reading the properties of the decoy user "Arthur". But there is a drawback. This creates a lot of logs and can also include false positives. We will work on in the next example
Decoy User 2
Setup
Creating a decoy user called "Louis" and turning on auditing when ‘x500uniqueIndentifier’ is read that is → d07da11f-8a3d-42b6-b0aa-76c962be719a
As per Microsoft, "Used to distinguish between objects when a distinguished name has been reused."
Here is the visual representation.
Code Explanation
The explanation of the whole code will be the same as above. The only difference will be in the "Set-AuditRule".
Now that we have set GUID (d07da11f-8a3d-42b6-b0aa-76c962be719a), the code will move into the "ElseIf" condition and set the new audit rule variable and then on lines 402 and 403, it will set the Audit Rule. After that everything is the same(refer to above).
Simulation And Detection
Now we will simulate the attack. The scenario is the same as above but this time we will use powerview.ps1 script.
Now use the powerview.ps1 "Get-NetUser" to get the properties of all the users.
Now checking the Event Viewer.
Event 4662 was triggered successfully. The event shows that the user Aizen was reading the properties of decoy user Louis. If you try the net.exe command, the logs will not be generated thus reducing the false positives.
Decoy SPN
Setup
In this, creating a decoy SPN named "MSSQL Server" and GUID of "f3a64788-5306-11d1-a9c5-0000f80367c1"
Now to make the deception more effective, I've configured GMSA(Group Managed Service Accounts) so that the decoy SPN looks like a real SPN. You get the idea right😉
So first adding the decoy SPN to the GMSA group.
Here is the visual representation of the domain environment.
Code Explanation
Just like we saw before the whole code will be the same as before but this time it has the "SPN" parameter.
After the "If" condition is true, the "Set-ADUser" will add the principal name to the decoy user.
Simulation And Detection
Using the same scenario. The command "Get-DomainUser -SPN" will return all the properties of SPNs in the domain.
MSSQL Server properties
This will generate the 4662 Event ID.
The Event 4669 will be triggered when the user Aizen tries to enumerate the SPN "MSSQL Server".
Reading DACL
Setup
Creating a decoy user Zack that has "ReadControl" right set, a 4662 will be generated when anyone reads the DACL of the decoy user.
Code Explanation
It will be the same as above with a minor difference. In the "Deploy-UserDeception" function the parameter's value will be different.
Storing passwords using reversible encryption is essentially the same as storing plaintext versions of the passwords
the same logic applies in the "If" statement and it's self-explanatory.
Simulation And Detection
The scenario is the same as above and the compromised user Aizen will try to read and enumerate the DACL of the decoy user Zack.
Checking back the logs.
Event 4662 is generated successfully.
Decoy Computer - No Real VM
Setup
Creating a decoy computer object name "Employee-Webserver" that has no actual VM and naming it with old windows vulnerable version.
Verifying it in Domain Controller.
The decoy computer is created successfully. Also if we check the OS version.
It says "Windows Server 2003" which is a decoy, also checking the unconstrained delegation.
Everything is configured properly.
Code Explanation
Focusing on the "Create-DecoyComputer" function.
Line 104 gets the computer-name parameter.
Line 110 will get and append the DNS name
It will move towards the else condition because it doesn't take the OU parameter and creates a computer object with the "New-ADComputer" command.
Now focusing on the "Deploy-ComputerDeception" function.
The parameters highlighted are called.
On line 1055, the "Set-ADComputer" will set the operating system property.
On line 1075, it will set the unconstrained delegation property.
On line 1081, the audit rule will be set
Simulation And Detection
The scenario is the same - here is the diagram for the adversary simulation.
Now running Powerview.ps1 command "Get-NetComputer"
The properties of "Employee-Webserver" are read.
Event 4662 generated, the user Aizen has read "Employee-Webserver" properties. The only drawback of not having an actual VM behind a decoy computer is that the powerview doesn't output a lot of data. So the adversary can easily identify this decoy computer.
Decoy Computer - Actual VM
Setup
Now create a decoy computer object name "EnterpriseDB" that has an actual Windows 7 VM attached to the domain. But to make it more interesting we will set the operating system to Windows Server 2012 and also set an unconstrained delegation to make it more lucrative to the adversary.
Verifying it like before.
The code logic will be the same as before so we won't be looking at it😅.
Simulation And Detection
You know it already☺️.
Running the powerview command "Get-NetComputer"
A Decoy computer that is running on a real VM outputs a lot of data and adversaries find it hard to identify the decoy computer object.
And as a defender, we detected that the user Aizen was trying to read the properties of the decoy computer object "Enterprise DB".
Decoy Groups
Setup
Adversaries often go after the groups that look more promising and lucrative. So let's create a decoy user "Database Admins" that is also a part of the higher priority domain group called "DNSAdmins". The decoy group has a decoy user "Louis" as a member. And a 4662 event will be generated when the adversary will try to read the DACL of the group
But wait we got an error here
Let's first try to see what the script does and then we will try to fix it.
Code Explanation And Fix
First focusing on the "Create-DecoyGroup" function on line 126.
The function first takes the group-name parameter on 152 and makes the group-scope global at line 157. And then it creates a group with the "New-ADGroup" cmdlet.
Now moving on to "Deploy-GroupDeception" on line 1084.
As per the command, the parameters will be selected that are highlighted.
Both the "If" statements will first verify if the parameters are true. Then it will use "Add-ADGroupMember" to add a user or group to a specific group.
Now if take a closer look at the error we got. It says the problem lies on line 168 in the "AuditFlag" parameter. It has a "String[]" which is a string array
If we remove the "[]"
How do I come to this conclusion??? If we see the "AuditFlag" on another functions we can see what was wrong here
To get more clear explanation refer to the link below
Now save the script and run the same command again.
Looks like we debugged our code.
The group is successfully created.
Simulation And Detection
Same as before.
After confirmation, now use the powerview command "Get-NetGroup 'Database Admins' " to enumerate the "Database Admins" group.
This will generate the log
The log was generated successfully indicating that the user Aizen was enumerating the properties of the decoy group "Database Admins"
Honey user
Setup
In this we will create a decoy user name "Hisoka" that will be added to the highest privilege group in the Domain called "Domain Admins", to prevent compromise of the DA group we will disable the login of the user "Hisoka" on every machine and creating a logon event profile on the DC.
Note - This method is a little risky and if misconfigured properly the adversary will have control over the whole Domain Admins group
Code Explanation
The function “Create-DecoyUser” will be the same as before. Focus on “Deploy-PrivilegedUserDeception”.
The parameters are defined as per the command.
Line 863 will confirm if the decoy user exists or not.
The technique selected as "DomainAdminsMemebership" will add the user to the DA group.
The above code snippet will deny the logon of user "Hisoka" on every machine.
Simulation And Detection
For this purpose, as a defender, we can leave the cleartext credentials of user "Hisoka" on any machine and try to make it hard to find so that the adversaries don't get suspicious.
In the first, if we enumerate the user "Domain Admins" properties using the powerview command "Get-NetGroupMember 'Domain Admins' ".
This command will generate two 4662 logs.
First, it will capture a log for Domain Admins
And second, will be for user Hisoka.
This might not be that helpful until we get confirmation that the adversary has got hold of user "Hisoka". For this purpose, we will utilize a tool called "PsExec".
The user "Hisoka" was denied logon the "Client01" machine.
We can see we caught the adversary in the act of logging in "Client01"
Fooling The Deception
Now that we understand how as a defender we can fool the adversary by deploying decoy objects. But as an adversary, there are a few tricks and tools that we can use to identify decoy objects.
HoneypotBuster
There is one tool from Javelin Network called "HoneypotBuster".
We can see that the tool has detected the decoy computer object "Employee-Webserver" that has no actual VM in the background but didn't detect "EnterpriseDB" because it had an actual VM behind it.
It has flagged all three SPNs as fake but if we look carefully at "MSSQL Server" we can see it doesn't have a working port.
It has detected both authenticate and decoy users as fake. Because it has a low login count, to avoid detection of the decoy DA user is to increase the login count.
Powerview Trick
The Powerview command "Get-DomainUser" will get the user's properties.
This in return generates a lot of logs that can get us caught. Specifying the properties requested with the "-Properties" flag prevents the x500uniqueIdentifier property from being requested on the decoy object
This will generate nearly fewer possible logs. The only log that was generated was for the user "Arthur" which we didn't configure properly.
This should be the perfect meme for this reference
Closure
Although there are many commercial deception tools that are more user-friendly and easy to use. In this, we only take a look at a Powershell-based tool.
As deception is getting more mainstream in the infosec industry adversaries always comes up with a more sneaky method to avoid detection every time and this is a never-ending race.
Last updated