Skip to main content

LDAP

Synopsis

Creates a decoy LDAP server that captures the credentials of every bind attempt — the cleartext password of a simple bind, or a crackable Net-NTLMv2 response from a SASL/NTLM bind. With Domain Controller emulation enabled, binds succeed and searches return fabricated Active Directory data, so reconnaissance tools keep enumerating and generate more telemetry.

Schema

- id: <numeric>
name: <string>
description: <string>
type: ldap
tags: <string[]>
pipelines: <pipeline[]>
status: <boolean>
properties:
address: <string>
port: <numeric>
os_flavor: <string>
emulate_dc: <boolean>
domain: <string>
dns_domain: <string>
computer_name: <string>
tls:
status: <boolean>
cert_name: <string>
key_name: <string>
timeout: <numeric>

Configuration

The following fields are used to define the device:

Device

FieldRequiredDefaultDescription
idYUnique identifier
nameYDevice name
descriptionN-Optional description
typeYMust be ldap
tagsN-Optional tags
pipelinesN-Optional pre-processor pipelines
statusNtrueEnable/disable the device

Connection

FieldRequiredDefaultDescription
addressN"0.0.0.0"Listen address
portYListen port
timeoutN20Idle timeout in seconds

Emulation

FieldRequiredDefaultDescription
os_flavorNserver2019Windows version advertised in the NTLM challenge

Accepted values are server2012, server2012r2, server2016, server2019, and server2022. Each preset supplies the NetBIOS and DNS computer and domain names, plus the Windows version reported to the client. Scanners and client tools fingerprint the host from these, so the value determines which Windows Server build the honeypot appears to be.

An unrecognized or empty value falls back to server2019 without raising a configuration error.

Domain Controller

FieldRequiredDefaultDescription
emulate_dcNfalseAnswer binds and searches as a Domain Controller
domainN-NetBIOS domain name, e.g. CORP
dns_domainN-DNS domain name, e.g. corp.local
computer_nameN-Domain Controller computer name, e.g. DC01

When emulate_dc is true and domain, dns_domain, or computer_name are left empty, the fallback identity CORP / corp.local / DC01 is used instead.

TLS

FieldRequiredDefaultDescription
tls.statusNfalseEnable implicit LDAPS on this listener
tls.cert_nameN-Certificate name resolved from the certificate store
tls.key_nameN*key.pemKey name resolved from the certificate store

* = Read only when tls.status is true and tls.cert_name is set.

note

Enabling tls.status turns on implicit LDAPS: the connection is TLS-wrapped before any LDAP byte is exchanged, typically on port 636 — this is not StartTLS. When tls.status is true and tls.cert_name is empty, a self-signed certificate is generated on every start.

The listener accepts TLS 1.0 and later. The minimum version is deliberately not raised to TLS 1.2, so that older LDAP clients still complete the handshake and get logged. It is fixed and cannot be configured on this device.

Details

Domain Controller Emulation

With emulate_dc left at false, every bind is logged and answered with invalidCredentials, and search requests are refused with unwillingToPerform.

With emulate_dc set to true, binds return success — the credential is still captured — and a RootDSE query (base "", scope 0) returns Domain Controller naming contexts: namingContexts, defaultNamingContext, rootDomainNamingContext, configurationNamingContext, schemaNamingContext, dnsHostName, serverName, ldapServiceName, isGlobalCatalogReady: TRUE, isSynchronized: TRUE, supportedLDAPVersion, supportedSASLMechanisms, and a domainControllerFunctionality/domainFunctionality/forestFunctionality of 7. Any other search returns a fabricated Domain Controller computer object — CN=DC01,OU=Domain Controllers,DC=corp,DC=local with sAMAccountName=DC01$, userAccountControl=532480, primaryGroupID=516, and the LDAP/ and HOST/ service principal names. Reconnaissance tools fingerprint the host as a Domain Controller from this data and keep enumerating, producing more telemetry.

Bind Capture

A simple bind captures the submitted DN and the cleartext password. A SASL bind extracts the NTLMSSP token: a NEGOTIATE message is answered with a CHALLENGE built from the os_flavor preset, overridden by computer_name, domain, and dns_domain when set, and the subsequent AUTHENTICATE message is parsed into a crackable Net-NTLMv2 response.

Logged Events

Each connection produces one or more of the following event types:

event_typeEmitted when
connectionThe client sends its first LDAP message
auth_attemptAn authentication attempt is made, using either a simple or a SASL/NTLM bind
searchA search request is received

Event Fields

Every event carries timestamp, event_type, source_ip, source_port, and local_addr. The remaining fields depend on the event type:

FieldDescription
usernameUsername or bind DN submitted in the attempt
passwordPassword submitted in a simple bind, in cleartext
domainNTLM domain captured from a SASL/NTLM bind
workstationNTLM workstation name captured from a SASL/NTLM bind
auth_methodAuthentication method used: simple or ntlm
netntlmv2Crackable Net-NTLMv2 response captured from a SASL/NTLM bind
os_flavorConfigured os_flavor preset for the session
base_objectBase DN requested in a search
is_rootdseWhether the search targeted the RootDSE
dc_queryWhether the search filter contains the LDAP_MATCHING_RULE_BIT_AND OID 1.2.840.113556.1.4.803, the classic SERVER_TRUST_ACCOUNT hunt for domain controllers

Captured Hashes

netntlmv2 is a hashcat -m 5600 Net-NTLMv2 string.

Examples

The following are commonly used configuration types.

Basic

Creating a minimal LDAP honeypot on the standard port...

devices:
- id: 1
name: basic_ldap
type: ldap
properties:
port: 389

Domain Controller Emulation

Emulating a Domain Controller so binds succeed and directory searches return fabricated AD data...

devices:
- id: 2
name: ldap_dc_emulation
type: ldap
properties:
port: 389
emulate_dc: true
domain: CORP
dns_domain: corp.local
computer_name: DC01

LDAPS

Running implicit LDAPS on port 636 with a self-signed certificate generated on each start...

devices:
- id: 3
name: ldaps_honeypot
type: ldap
properties:
port: 636
tls:
status: true

With Pre-Processing

Routing captured attempts through a pre-processing pipeline before ingestion...

devices:
- id: 4
name: ldap_preprocessed
type: ldap
pipelines:
- decoy-honeypot-enrich
properties:
port: 389

A simple bind is logged with the cleartext credential before pipeline processing...

{
"timestamp": "2026-08-03T09:14:22.481937204Z",
"event_type": "auth_attempt",
"source_ip": "203.0.113.44",
"source_port": "51422",
"local_addr": "10.0.4.12:389",
"username": "cn=admin,dc=corp,dc=local",
"password": "Summer2026!",
"auth_method": "simple",
"os_flavor": "server2019"
}