Active Directory Canaries is a detection primitive for Active Directory enumeration (or recon) techniques. It abuses the concept of DACL Backdoors, introduced by Specter Ops researchers Andy Robins (@_wald0) and Will Schroeder (@harmj0y) back in 2017 in their white paper “An ACE Up the Sleeve”.
The purpose of this project is to publish and maintain the deployment PowerShell script that automates required AD object deployments.
AD Canaries deployment requires AD admin permission, and involves deploying several new AD objects to production. Although these objects are isolated and hardened, we strongly invite you to review the code before and test it before any in-production deployment.
AD Canaries detection is based on Directory Service Object Access : Failure
audit which generates a 4662 event in the Security eventlog on your domain controller upon AD enumeration behaviours (i.e access attempt on any canary object).
IMPORTANT: AD Canaries deployment requires AD Admin privileges
Usage : ./ADCanaries.ps1 -Populate -Config <Path> -ParentOU <OU> \
-Owner <Principal|Group Name> \
-CanaryContainer <Name> : 'Populate default ADCanaries deployment; overwrites json config file provided.'
-Deploy -Config <Path> -Output <Path> : 'Deploy ADCanaries using json configuration file and outputs lookup CSV with CanaryName,CanaryGUID'
-Revert -Config <Path> : 'Destroy ADCanaries using json configuration file'
-AuditSACLs : 'Display the list of existing AD objects with (ReadProperty|GenericAll) audit enabled to help measure DS Access audit failure activation impact'
-GetObjectPropertiesGuids -Output <Path> : 'Retreives the schemaIDGuid for attributes of Canaries objectClass and outputs as csv'
Optional : Auditing existing SACLs within the environment
./ADCanaries.ps1 -AuditSACLs
In the following example, we chose to deploy inside the OU ‘OU=CORIIN-DEMO,DC=SYLVESTER,DC=LABS’ and configure ‘Domain Admins’ as owner :
./ADCanaries.ps1 -Populate -Config ADCanaries.json -ParentOU 'OU=CORIIN-DEMO,DC=SYLVESTER,DC=LABS' -Owner 'Domain Admins' -CanaryContainer 'GrosMinet'
Specify the pre-existing ParentOU in which you want to deploy the canaries, and the deployed OU name. Try to make these blend as much as possible in your environment as those are the only objects that will be visible after full deployment.
Populate will generate a JSON config file that you can customize to your liking ahead of deployment:
{
“Configuration”: {
“CanaryOwner”: “Domain Admins”,
“CanaryGroup”: {
“OtherAttributes”: {},
“Description”: “[ADCanaries] Canaries primary group -- [VISIBLE TO ATTACKERS] change it”,
“Type”: “group”,
“ProtectedFromAccidentalDeletion”: 1,
“Name”: “TEST”,
“Path”: “CN=TEST,OU=TEST,DC=CYBERLAB,DC=NET”
},
“CanaryContainer”: {
“OtherAttributes”: {},
“Description”: “[ADCanaries] Default container -- [VISIBLE TO ATTACKERS] change it”,
“Type”: “container”,
“ProtectedFromAccidentalDeletion”: 1,
“Name”: “TEST”,
“Path”: “OU=TEST,DC=CYBERLAB,DC=NET”
}
},
“Canaries”: [
{ “OtherAttributes”: {},
“Description”: “[ADCanaries] Default User Canary -- change it”,
“Type”: “user”,
“ProtectedFromAccidentalDeletion”: 1,
“Name”: “CanaryUser”,
“Path”: “CN=TEST,OU=TEST,DC=CYBERLAB,DC=NET”
},{ “OtherAttributes”: {},
“Description”: “[ADCanaries] Default Computer Canary -- change it”,
“Type”: “computer”,
“ProtectedFromAccidentalDeletion”: 1,
“Name”: “CanaryComputer”,
“Path”: “CN=TEST,OU=TEST,DC=CYBERLAB,DC=NET”
},{ “OtherAttributes”: {},
“Description”: “[ADCanaries] Default Group Canary -- change it”,
“Type”: “group”,
“ProtectedFromAccidentalDeletion”: 1,
“Name”: “CanaryGroup”,
“Path”: “CN=TEST,OU=TEST,DC=CYBERLAB,DC=NET”
},{ “OtherAttributes”: {},
“Description”: “[ADCanaries] Default CertificateTemplate Canary -- change it”,
“Type”: pKICertificateTemplate,
“ProtectedFromAccidentalDeletion”: 1,
“Name”: “CanaryCertTemplate”,
“Path”: “CN=TEST,OU=TEST,DC=CYBERLAB,DC=NET”
},
...
]
}
NB: AD canaries are deployed as AD objects, you can configure other type of canaries by specifying existing AD Objects type such as :
To uncover enumeration of this types of objects within your domains.
/!\ you might need some troubleshouting when implementing non standard canary objects /!\
Will deploy all AD objects, disable inheritance, change owner and default primary group, configure SACLs and remove all permissions with an explicit DENY on Everyone :
./ADCanaries.ps1 -Deploy -Config ADCanaries.json -Output CanaryGuids.csv
IMPORTANT: Backup the JSON config file as it will be required to delete the deployed objects using -Revert option !
Now if you have properly configured auditing, you should be able to test 4662 (DS Access failure)event generation upon AD enumeration. Example of detection query in KQL (with pivot on 4624 logon event to enrich) :
SecurityEvent
| where EventID == 4662 and ObjectServer == “DS”
| extend Object = tostring(split(split(ObjectName, “{“)[1], “}”)[0]),
AccessedProperties = extract_all(@”\{([a-fA-F\d]{8}-[a-fA-F\d]{4}-[a-fA-F\d]{4}-[a-fA-F\d]{4}-[a-fA-F\d]{12})\}”, Properties)
// ADCanaries.csv generated when deploying via the aforementioned script
| lookup kind=inner _GetWatchlist(“ADCanaries”) on $left.Object==$right.SearchKey
| mv-expand AccessedProperties
| extend Prop = tostring(AccessedProperties)
// PropertiesGUIDs.csv generated when deploying via the aforementioned script
| lookup kind=leftouter _GetWatchlist(“PropertiesGUIDs”) on $left.Prop==$right.SearchKey
// Simple DIY lookup table using MS documentation for event 4662
| lookup kind=leftouter _GetWatchlist(“AccessTypes”) on $left.AccessMask==$right.SearchKey
| join kind = leftouter (
SecurityEvent
| where EventID == 4624 and LogonType == 3
) on $left.Computer==$right.Computer and $left.SubjectLogonId==$right.TargetLogonId and $left.SubjectUserName==$right.TargetUserName
// Some aggregation here, not optimal
| summarize Count=count(), AccessedProps=makeset(ldapDisplayName), LogonIds=makeset(SubjectLogonId), Accesses=makeset(Access), IPs=makeset(IpAddress1), Devices=makeset(WorkstationName1)
by bin(TimeGenerated, 1m), SubjectUserName, SubjectDomainName, CanaryName
// Don’t forget to add fine tuned exclusions on normal behavior here
We relyed a lot on the specific set of AccessedProperties to identify and exclude on legitimate AD enumeration within a production environment.
These properties are present in the generated 4662 event, but with only a GUID. You can use the ‘-GetObjectPropertiesGuids’ option to create a non-exhaustive CSV lookup of object properties within your environment and associated GUIDs:
./ADCanaries.ps1 -GetObjectPropertiesGuids -Output AccessPropertiesGuids.csv
Deleting everything based on the JSON file
./ADCanaries.ps1 -Revert -Config ADCanaries.json
You can also remove manually the deployed objects; from a domain admin session using AD Users & Computers console :
- Who initiated this enumeration ?
- Source event 4662
- What was enumerated ?
- Enrichment from source event
- From where was this initiated ?
- Pivot: Logon event 4624
- What is the behavior behind this enumeration ?
- Pivot: Identified asset’s telemetry
- Process executions
- File creations
- Network connections
- RPC calls
- …
- Do I see any other “classic” attack patterns ?
- Pivot: Identified account Kerberos activity
- Pivot: Network telemetry
shadow-rs is a Windows kernel rootkit written in Rust, demonstrating advanced techniques for kernel manipulation…
Extract and execute a PE embedded within a PNG file using an LNK file. The…
Embark on the journey of becoming a certified Red Team professional with our definitive guide.…
This repository contains proof of concept exploits for CVE-2024-5836 and CVE-2024-6778, which are vulnerabilities within…
This took me like 4 days (+2 days for an update), but I got it…
MaLDAPtive is a framework for LDAP SearchFilter parsing, obfuscation, deobfuscation and detection. Its foundation is…