LDAP Firewall
is an open-source tool for Windows servers that lets you audit and restrict incoming LDAP requests.
Its primary use-cases are to protect Domain Controllers, block LDAP-based attacks and tightly control access to the Active Directory schema (e.g enforcing read-only access for users).
The tool is written in C++ and makes use of the Microsoft Detours and JsonCpp packages.
Some useful resources to get you started:
- Introduction blog post - basics of LDAP and overview of the tool
- Technical Deep Dive blog post - reverse-engineering the Windows LDAP service and how LDAP Firewall works
- Leash the Hounds - how to stop BloodHound and other LDAP-based recon attacks using the LDAP Firewall
- A Defender’s Guide to DACL-Based Attacks via the LDAP Firewall - explanations and example configurations for how to prevent various LDAP attacks
- Tutorial video - covers how to install and use the tool
- LDAP Firewall Workshop video - from DEATHCon 2023
- Allow / block incoming LDAP queries based on different parameters (operation type, source IP, user, DN etc.)
- Event logging for LDAP queries
The LDAP Firewall inspects incoming LDAP operations (which are used to read or modify entries in the AD schema) and allows or blocks the request based on the configured rules.
The operation also gets written into the Windows Event Log with the LDAPFW action and other relevant fields (Distinguished Name, attributes, OID etc.).
- Security Engineers who want to control LDAP access and achieve a Least Privilege model
- Threat Hunters and SOC analysts who want to be create detections and perform investigations around LDAP
- Security Researchers who want to explore and deepen their understanding of the protocol
This section describes some common LDAP-based attacks that can be mitigated with the LDAP Firewall.
Sample config.json files can be found in the example_configs folder of this repository.
Stop BloodHound scans by blocking searches on uncommon attributes (such as admincount, userpassword and msds-allowedToDelegateTo).
SharpHound unable to obtain entities from LDAP
LDAPFW blocking the BloodHound search operation
This attack allows for taking over an account by modifies a user’s KeyCredentialLink attribute. With the LDAP Firewall, you can block modify operations that try to edit this attribute.
Whisker unable to modify the KeyCredentialLink attribute
Mitigate Kerberoasting and Targeted Keberoasting attacks by preventing access to the servicePrincipalName attribute.
GetUserSPNs unable to enumerate kerberoastable targets
Targeted Kerberoasting unable to modify the servicePrincipalName attribute
Protect LAPS passwords by monitoring and blocking attempts to read the ms-Mcs-AdmPwd computer attribute.
Get the latest binary from the release page, or build from source.
Currently supported and tested on Windows Server 2016 and up.
Internet access is required for fetching symbols from the Microsoft public symbol server.
- If you get an error about missing DLLs (VCRUNTIME140.dll / MSVCP140.dll), install the Microsoft Visual C++ 2015 - 2022 Redistributable.
- If you get an "Error when calling VirtualAllocEx 5" message when installing LDAPFW, check whether Windows Defender has Attack Surface Reduction enabled (rule GUID 9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2). The easiest solution is to add ldapFwManager.exe as an exclusion.
ldapFwManager.exe /help
Usage: ldapFwManager /<Command> [options]
Command:
----------
/install - install LDAP Firewall as a service
/uninstall - remove LDAP Firewall service
/update - reload config.json and update the LDAPFW configuration (while installed)
/status - print status
/validate - verify that the config.json file is formatted correctly
/help - show this message and exit
Before installing LDAPFW for the first time, run with /status
to make sure all prerequisites are met:
ldapFwManager.exe /status
LDAP Firewall v1.0.1
Status:
---------------------
LDAPFW Installed: False
Symbols loaded: True
Ready to install: True
All configurations are set in the config.json
file.
{
"rules": [
{
"operations": ["search"],
"attributes": ["admincount", "userpassword", "msds-allowedToDelegateTo", "ms-Mcs-AdmPwd"],
"audit": "on"
},
{
"operations": ["search"],
"audit": "off"
},
{
"operations": ["*"],
"action": "allow",
"audit": "on",
}
]
}
Note: to turn on verbose logging (written to LDAPFW.log), add the following key:
{
"rules": [
{
...
}
],
"debug": "on"
}
The rules
field specifies a list of block / allow rules similar to a classic firewall. Each rule can be defined with the following fields:
- operations - list of LDAP operations (add / delete / modify / modifydn / search / compare / extended or
*
for any) - ips - list of source IPs / CIDR subnets (or
*
for any) - users - list of users (or
*
for any) - groups - list of groups (or
*
for any) - action - action to perform (allow / block)
- audit - log operation in the Event Log (on / off)
- dn - DN set in the LDAP query (if applies)
- attributes - list of attributes set in the LDAP query (if applies)
- oid - OID set in the LDAP query (if applies)
- filter - filter set in a Search query
- scope - scope set in a Search query (Base / One Level / Subtree)
During an incoming LDAP operation, the first matched rule action applies. If no rule matches, the operation is allowed by default (this behaviour can be modified by setting a global block rule as the final rule).
Note: in the default configuration, Search operations do not generate event logs (except when searching for specific attributes) as the logs can get noisy. This behaviour can be modifying by changing the audit rules.
Message ID | Symbolic Name | Description |
---|---|---|
257 | LDAP_PROTECTION_ADDED | LDAP Firewall protection installed. |
258 | LDAP_PROTECTION_REMOVED | LDAP Firewall protection removed. |
259 | LDAP_ADD_CALL | An LDAP Add operation was called. |
260 | LDAP_DELETE_CALL | An LDAP Delete operation was called. |
261 | LDAP_MODIFY_CALL | An LDAP Modify operation was called. |
262 | LDAP_MODIFYDN_CALL | An LDAP Modify DN operation was called. |
263 | LDAP_SEARCH_CALL | An LDAP Search operation was called. |
264 | LDAP_COMPARE_CALL | An LDAP Compare operation was called. |
265 | LDAP_EXTENDED_CALL | An LDAP Extended operation was called. |
266 | LDAP_CONFIG_UPDATED | LDAP Firewall configuration updated. |
The LDAP Firewall is built from 3 main components:
Main executable which loads the configuration, sets up the environment and injects the firewall into lsass.exe
(the main Windows process which enforces the security policy and handles LDAP connections in Windows servers).
The actual LDAP Firewall code, which detours the internal Windows LDAP functions in order to manage and audit LDAP requests.
Handles writing audit messages to the Windows Event Log, which are written to Application and Services Logs\LDAPFW
.
Yes! Don't be shy to do a pull request.
For any questions, issues, or simply to shout out, join our -273°C Slack channel where the community shares best practices and helps build better defenses using open-source tools.
We are also available at [email protected].
For more details, see LICENSE.