This post is the first part of a series in which we will cover the concept of using honeypots in a Windows environment as an easy and cost-effective way to detect attacker (or red team) activities. Of course this blog post is about catching real attackers, not just red teams. But we picked this catchy title as the content is based on our red teaming experiences.
Upon mentioning honeypots, a lot of people still think about a system in the network hosting a vulnerable or weakly configured service. However, there is so much more you can do, instead of spawning a system. Think broad: honey files, honey registry keys, honey tokens, honey (domain) accounts or groups, etc.
In this post, we will cover:
- The characteristics of an effective honeypot.
- Walkthrough on configuring a file- and registry based honeypots using audit logging and SACLs.
- Example honeypot strategies to catch attackers using popular local reconnaissance tools such as SeatBelt and PowerUp.
Characteristics of a good honeypot
For the purpose of this blog, a honeypot is defined as an object under your (the defender’s) control, that is used as a tripwire to detect attacker activities: read, use and/or modification of this object is monitored and alerted upon.
Let’s start by defining what a good honeypot should look like. A good honeypot should have at least the following characteristics:
- Is easily discovered by an attacker (i.e. low hanging fruit)
- Appears too valuable for an attacker to ignore
- Cannot be identified as ‘fake’ at first sight
- Abuse can be easily monitored (i.e. without many false positives)
- Trigger allows for an actionable response playbook
It is extremely important that the honeypots you implement, adhere to the characteristics above. We have performed multiple red teaming gigs in which the client told us during the post-engagement evaluation session that they did implement honeypots using various techniques, however we did not stumble across them and/or they were not interesting enough from an attacker’s perspective.
Characteristics of local reconnaissance
When an attacker (or red teamer) lands on a system within your network, he wants to gain contextual information about the system he landed on. He will most likely start by performing reconnaissance (also called triage) on the local system to see what preventive and detective controls are in place on the system. Important information sources to do so are configuration and script files on the local system, as well as registry keys.
Let’s say you are an attacker, what files and registry would you be interested in, where would you look? Some typical examples of what an attacker will look for are:
- Script folders on the local drive
- Currently applied AppLocker configuration
- Information on installed antivirus/EDR products
- Configuration of log forwarding
- Opportunities for local privilege escalation and persistence
A good example of common local recon activities can be gathered from the command overview of the Seatbelt project.
Catching local enumeration tools
There are tons of attacker tools out there that automate local reconnaissance. These tools look at the system’s configuration and standard artefacts that could leak credentials or other useful information. Think of enumerating good old Sysprep/unattend.xml files that can store credentials, which are also read out by tools like SharpUp, PowerUp, and PrivescCheck:
Next to files, there are also quite some registry keys that are often enumerated by attackers and/or reconnaissance tooling. A few examples are:
- AllwaysInstallElevated (SharpUp, PowerUp, PrivescCheck)
- AppLocker configuration (Seabelt -group=system)
- Credential store reconnaissance and RDP saved connections (Seabelt -group=user, SessionGopher)
As a defender, you can build honeypots for popular files and registry keys that are opened by these tools and alert upon opening by suspicious process-user combinations. Let’s dive into how this can be achieved on a Windows system.
File- and registry-based honeypots
A file-based honeypot is a dummy file (i.e. a file not really used in your environment) or legit file (i.e. Unattend.xml or your Sysmon configuration file) for which audit logging is configured. You do this by configuring a so-called SACL (System Access Control list, more on this below) for the specific file. The same approach can be used to configure audit logging for a certain registry key.
The remainder of this post will guide you through configuring the audit logging prerequisites for file- and registry auditing, as well as the configuration of a SACL for a file/registry key.
First things first: what is a SACL?
You might have heard the terms SACL and DACL before. In a nutshell, it goes as follows: any securable object on your Windows system (i.e., file, directory, registry key, etc.) has a DACL and a SACL.
- A DACL is used to configure who has what level of access to a certain object (file, registry entry, etc.).
- A SACL is used to configure what type of action on an object is audited (i.e., when should an entry be written to the local system’s Security audit log).
So, amongst others, a SACL can be used to generate log entries when a specific file or registry key is accessed.
Prerequisite: configuring auditing of object access
To implement a file-based honeypot, we first need to make sure that auditing for object access is enabled on the system where we want to create the file- or registry based honeypot. The required object auditing categories are not enabled by default on a Windows system.
Enabling auditing of file- and registry access can be done using a Group Policy. Create a new GPO and configure the options below:
- ‘Audit File System’ audit ‘success‘ and ‘failure‘.
- ‘Audit Registry’ audit ‘success‘ and ‘failure‘.
These policies can be found under ‘Computer Configuration’ -> ‘Policies’ -> ‘Windows Settings’ -> ‘Security Settings’ -> ‘Advanced Audit Configuration’ -> ‘Object Access’:
Once you configured your GPO, you can use the auditpol command line utility to see if the GPO has been applied successfully. Below example output of the command on a test system:
auditpol /get /category:"object access"
NB: if the configured settings are not being applied successfully, your environment might have GPOs configured that make use of old-school high-level audit policies instead of advanced audit policies. Review if this is the case and migrate them to advanced audit policies. If you have multiple GPOs that specify ‘Advanced Audit Policies’, you might need to enable ‘Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings’ in your ‘Default Domain Policy’.
Configuring auditing for a specific file
Now that auditing of object access is configured, let’s enable access logging for a specific file. We do this by configuring a so-called SACL. Right-click -> Properties on the file you want to configure access monitoring for and use the security tab -> advanced to configure an auditing rule for the principal ‘Everyone’, and select ‘List folder / read data’.
You can also do so using PowerShell. For this, use the code snippet below.
#File for which auditing to be configured $FileToAudit = "c:\Windows\Panther\Unattend.xml" # Set properties for new SACL $AuditIdentity = "Everyone" # who to audit $AuditOnAction = "ReadData" # what action to audit. Other actions could be: "Write, TakeOwnership". More info: https://docs.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.filesystemrights?view=net-5.0 $AuditType = "Success" # Audit action "Success" $InheritanceFlags = "None" # Not inherited by child objects $PropagationFlags = "None" # Don't propagate to child objects $NewAuditACE = New-Object System.Security.AccessControl.FileSystemAuditRule($AuditIdentity,$AuditOnAction,$InheritanceFlags,$PropagationFlags,$AuditType) # Get the currently configured ACL $Acl = Get-Acl $FileToAudit -Audit # Add the ACE, preserving previously configured entries $Acl.AddAuditRule($NewAuditACE)
Making a file look more interesting/legit
For the purpose of this blog post I created an Unattend.xml file in the ‘c:\windows\panther’ folder. It has the date modified of today, in contrast to all the other files, which have their date modified set to the installation time of this host. Unattend.xml is normally not modified after finishing the installation and configuring of the system. The fact that the file has a very recent date modified, could alert an attacker in this file being a dummy file, refraining from opening it.
Let’s ‘timestomp’ the fake Unattend.xml file, making it look like it was created on the same date:
$file=(gi Unattend.xml); $date='02/15/2021 08:04'; $file.LastWriteTime=$date; $file.LastAccessTime=$date; $file.CreationTime=$date
Generated log entry for file access
Once audit logging is configured, an event with event ID 4663 is generated every time the file is accessed. This log entry contains the user and process that is used to access the file.
Configuring auditing for a specific registry key
We can use the same approach to configure auditing for registry settings. Let’s configure audit logging to detect the enumeration of the configured AppLocker policy. Open the registry editor and navigate to the AppLocker policy location: ‘HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\SrpV2’. Right click -> Properties on the ‘SrpV2’ folder. Click on ‘advanced’ and use the ‘Auditing’ tab of the ‘Advanced Security Settings’ to configure anauditing rule for the principal ‘Everyone’, and select ‘Query Value’ (screenshot below).
NB: if you do not have AppLocker configured within your environment, you can create a dummy registry entry in the location above. Another option is to deploy a dummy AppLocker configuration with default rules, without actually enforcing ‘block’ or ‘audit’ mode in the AppLocker Policy itself. This does create registry entries under SrpV2, but does not enforce an AppLocker configuration.
#Registry key for which auditing is to be configured $RegKeyToAudit = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\SrpV2" # Set properties for new SACL $AuditIdentity = "Everyone" # who to audit $AuditOnAction = "QueryValue" # what action to audit. Other actions could be: "CreateSubKey, DeleteSubKey". More info: https://docs.microsoft.com/en-us/dotnet/api/microsoft.win32.registrykey?view=dotnet-plat-ext-5.0#methods $AuditType = "Success" # Audit action "Success" $InheritanceFlags = "ContainerInherit,ObjectInherit" # Entry is inherited by child objects $PropagationFlags = "None" # Don't propagate to child objects $NewRegistryAuditACE = New-Object System.Security.AccessControl.RegistryAuditRule($AuditIdentity,$AuditOnAction,$InheritanceFlags,$PropagationFlags,$AuditType) # Get the currently configured ACL $Acl = Get-Acl $RegKeyToAudit -Audit # Add the ACE, preserving previously configured entries $Acl.AddAuditRule($NewRegistryAuditACE) # Apply the new configuration $Acl | Set-Acl | Out-Null
Generated log entry for registry access
Once audit logging is configured, an event with event ID 4663 is generated every time the registry key is accessed. This log entry contains the user and process that is used to access the file.
Centralised logging & alerting
Now that file auditing is configured on the system, make sure that at least event ID 4663 is forwarded to your central log management solution. If you have yet to configure Windows log forwarding, please refer to Palantir’s blog post for an extensive overview of Windows Event Forwarding.
Alerting and contextual awareness
After making sure that the newly generated events are available in your central log management solution, you can use this data to define alerting rules or perform hunts. While doing this, contextual information is important. Every environment is different. For example: there might be periodic processes in your organisation that access files for which you configured file auditing.
Things to keep in mind when defining alerting rules or performing hunts:
- Baseline normal activity: what processes and subjects legitimately access the specific file on disk periodically?
- Beware to not exclude a broad list of processes for alerting. The screenshot that shows an example event ID 4663, earlier in this post, shows dllhost.exe as the source process of opening a file. This is the case when you copy/paste a file.
Suggestions for files and registry keys to track using SACLs
When creating file-based honeypots, always keep in mind the characteristics of a good honeypot that are covered in the beginning of this post: easy to discover for attacker, too valuable to ignore, can’t be identified as fake, easy to monitor and having a playbook to respond.
Also keep in mind that reconnaissance tools enumerate file- and registry locations regardless of what software is installed. Even if you do not use specific software within your environment, you can create certain dummy files or registry locations. An added benefit of this could be: less false-positives out of the box for your environment, less fine-tuning of alerting required.
A couple of examples that could be worth implementing:
- AppLocker configuration. Any read access to the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\SrpV2, from an unexpected process.
- Saved RDP sessions. RDP sessions can be stored in the local user’s registry. Any read access to the registry key HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client, from an unexpected process.
- Interesting looking (dummy) script. If you have a local scripts folder on workstations, add a dummy script with a juicy name like resetAdminpassword.ps1 and monitor for read access. Make sure the file has some dummy content. Content of this file should not be able to influence the environment.
- Browser credential stores. Any read access to browser credential stores such as of Chrome or Firefox, that does not originate from the browser process. If you do not use a certain browser in your environment, planing fake browser credential stores in user’s roaming profiles can also be used as a trigger.
- Other credential stores/private keys. Any read access to SSH private keys, Azure session cookie files, or password databases that are used by users, that does not originates from an unexpected process.
- Sysmon configuration file. Any read access to the Sysmon configuration file of the local system, that does not originate from the Sysmon process.
- Windows installation/configuration artefacts. Any read access to Unattend.xml in C:\Windows\Panther, as covered in this blog post.
- Interesting (dummy) files on NETLOGON. Any read access to a file that looks like a legacy script or configuration file, located on the domain controller’s NETLOGON share.
Do you have suggestions for other great honeypots? Ping me on Twitter.
Future posts in this series will cover using SACLs for amongst others domain-based reconnaissance and specific attacks.