ldapsearch
ldapsearch is the OpenLDAP command-line search client shipped in the base macOS image. It opens a connection to an LDAP server, binds either anonymously, with simple credentials, or over SASL, and returns matching directory entries as LDIF. On a Mac that is bound to Active Directory, or on any host that can reach a domain controller, it is a native way to enumerate the directory - users, groups, computers, service principal names, and account control flags - using either credentials supplied on the command line or the host's existing Kerberos ticket. Because it is already present and signed by Apple, an operator can perform the reconnaissance that would otherwise require dropping a dedicated collector to disk.
Paths
/usr/bin/ldapsearch Example Use Cases
Enumerate directory users with a simple bind #
With a valid set of domain credentials (or against a server that permits anonymous binds), ldapsearch performs a subtree search from the domain naming context and returns account objects and their attributes. This maps usernames, descriptions, and group memberships without touching any Windows tooling. It requires network reach to the LDAP port (389) on a domain controller and, on most Active Directory deployments, valid credentials because anonymous binds are disabled by default.
ldapsearch -x -H ldap://<DC_IP> -D "<USER>@<DOMAIN>" -w '<PASSWORD>' -b "DC=<DOMAIN>,DC=<TLD>" -LLL "(objectClass=user)" sAMAccountName description memberOf Enumerate the directory using the host Kerberos ticket #
The -Y GSSAPI option authenticates the bind with the SASL GSSAPI mechanism, which uses the Kerberos credential cache of the current user instead of a password. On an Active-Directory-bound Mac, or on a host where the user already holds a valid ticket-granting ticket, this enumerates the directory with no password on the command line and no separate credential capture. -Q keeps SASL from prompting.
ldapsearch -Y GSSAPI -Q -H ldap://<DC_IP> -b "DC=<DOMAIN>,DC=<TLD>" -LLL "(objectClass=computer)" dNSHostName operatingSystem Identify Kerberoastable service accounts #
An LDAP filter that matches user objects carrying a servicePrincipalName returns the accounts whose Kerberos service tickets can be requested and cracked offline (Kerberoasting). ldapsearch surfaces these targets directly from the directory. It needs a valid bind and the servicePrincipalName attribute is a standard Active Directory attribute.
ldapsearch -x -H ldap://<DC_IP> -D "<USER>@<DOMAIN>" -w '<PASSWORD>' -b "DC=<DOMAIN>,DC=<TLD>" -LLL "(&(objectClass=user)(servicePrincipalName=*))" sAMAccountName servicePrincipalName Identify AS-REP roastable accounts #
The userAccountControl bitwise filter (matching rule OID 1.2.840.113556.1.4.803) with the value 4194304 selects accounts that do not require Kerberos pre-authentication. For those accounts an AS-REP hash can be requested without knowing the password and cracked offline (AS-REP roasting). ldapsearch returns the candidate list from a single query with a valid bind.
ldapsearch -x -H ldap://<DC_IP> -D "<USER>@<DOMAIN>" -w '<PASSWORD>' -b "DC=<DOMAIN>,DC=<TLD>" -LLL "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" sAMAccountName Bulk-dump the directory to a file with paged results #
The -E pr search extension requests LDAP paged results, which lets a single query retrieve the entire directory past the server's default result cap. Writing the LDIF to a file stages a full offline copy of the directory for later analysis. It requires a valid bind and read access to the objects returned.
ldapsearch -x -H ldap://<DC_IP> -D "<USER>@<DOMAIN>" -w '<PASSWORD>' -b "DC=<DOMAIN>,DC=<TLD>" -LLL -E pr=1000/noprompt "(objectClass=*)" > /tmp/dirdump.ldif Read LAPS local administrator passwords #
Where Microsoft LAPS is deployed, the local administrator password is stored on the computer object in the ms-Mcs-AdmPwd attribute. ldapsearch reads it directly when the bound account has been delegated read access to that attribute - a common privilege-escalation path when a compromised account or group holds LAPS read rights it should not. The attribute returns empty for principals without the delegated permission.
ldapsearch -x -H ldap://<DC_IP> -D "<USER>@<DOMAIN>" -w '<PASSWORD>' -b "DC=<DOMAIN>,DC=<TLD>" -LLL "(objectClass=computer)" ms-Mcs-AdmPwd ms-Mcs-AdmPwdExpirationTime Detections
- Command-line detection: /usr/bin/ldapsearch invoked with directory-recon filters (servicePrincipalName=*, userAccountControl bitwise filters, objectClass=user/computer against a domain naming context)