LDAP
A lot of information on an AD domain can be obtained through LDAP. Most of the information can only be obtained with an authenticated bind but metadata (naming contexts, DNS server name, Domain Functional Level (DFL)) can be obtainable anonymously, even with anonymous binding disabled.
::: tabs
=== ldeep
The ldeep (Python) tool can be used to enumerate essential information like delegations, gpo, groups, machines, pso, trusts, users, and so on.
# remotely dump information
ldeep ldap -u "$USER" -p "$PASSWORD" -d "$DOMAIN" -s ldap://"$DC_IP" all "ldeepdump/$DOMAIN"
# parse saved information (in this case, enumerate trusts)
ldeep cache -d "ldeepdump" -p "$DOMAIN" trusts
=== ldapsearch
The ldapsearch (C) tool can also be used.
# list naming contexts
ldapsearch -h "$DC_IP" -x -s base namingcontexts
ldapsearch -H "ldap://$DC_IP" -x -s base namingcontexts
# enumerate info in a base (e.g. naming context = DC=DOMAIN,DC=LOCAL)
ldapsearch -h "$DC_IP" -x -b "DC=DOMAIN,DC=LOCAL"
ldapsearch -H "ldap://$TARGET" -x -b "DC=DOMAIN,DC=LOCAL"
=== ldapsearch-ad
The ldapsearch-ad Python script can also be used to enumerate essential information like domain admins that have their password set to never expire, default password policies and the ones found in GPOs, trusts, kerberoastable accounts, and so on.\
ldapsearch-ad --type all --server "$DC_IP" --domain "$DOMAIN" --username "$USER" --password "$PASSWORD"
The FFL (Forest Functional Level), DFL (Domain Functional Level), DCFL (Domain Controller Functionality Level) and naming contexts can be listed with the following command.\
ldapsearch-ad --type info --server "$DC_IP" --domain "$DOMAIN" --username "$USER" --password "$PASSWORD"
=== windapsearch
The windapsearch script (Go (preferred) or Python) can be used to enumerate basic but useful information.
# enumerate users (authenticated bind)
windapsearch -d "$DOMAIN" -u "$USER" -p "$PASSWORD" --dc "$DC_IP" --module users
# enumerate users (anonymous bind)
windapsearch --dc "$DC_IP" --module users
# obtain metadata (anonymous bind)
windapsearch --dc "$DC_IP" --module metadata
=== ldapdomaindump
ldapdomaindump is an Active Directory information dumper via LDAP, outputting information in human-readable HTML files.
ldapdomaindump --user "$DOMAIN"\\"$USER" --password "$PASSWORD" --outdir ldapdomaindump "$DC_IP"
=== ntlmrelayx
With Impacket's ntlmrelayx (Python), it is possible to gather lots of information regarding the domain users and groups, the computers, ADCS, etc. through a NTLM authentication relayed within an LDAP session.
ntlmrelayx -t ldap://"$DC_IP" --dump-adcs --dump-laps --dump-gmsa
=== Invoke-PassTheCert
With the Invoke-PassTheCert fork, we may dump LDAP entries or ACEs as follows, authenticating through Schannel via PassTheCert (PowerShell version).
Note: the README contains the methodology to request a certificate using certreq from Windows (with a password, or an NTHash).
# Import the PowerShell script and show its manual Import-Module .\Invoke-PassTheCert.ps1 .\Invoke-PassTheCert.ps1 -? # Authenticate to LDAP/S $LdapConnection = Invoke-PassTheCert-GetLDAPConnectionInstance -Server 'LDAP_IP' -Port 636 -Certificate cert.pfx # List all the available actions Invoke-PassTheCert -a -NoBanner # Dump any LDAP object in the 'ADLAB.LOCAL' domain, then extract the ones with the WORKSTATION_TRUST_ACCOUNT, or NORMAL_ACCOUNT UAC flags $DumpLdap = Invoke-PassTheCert -Action 'Filter' -LdapConnection $LdapConnection -SearchBase 'DC=ADLAB,DC=LOCAL' -SearchScope Subtree -Properties * -LDAPFilter '(objectClass=*)' $DumpLdap |?{$_.sAMAccountName -ne $null -and ($_.useraccountcontrol -like '*WORKSTATION_TRUST_ACCOUNT*' -or $_.useraccountcontrol -like '*NORMAL_ACCOUNT*')} |Select-Object sAMAccountName,description,useraccountcontrol,distinguishedname,serviceprincipalname |fl # Dump all the inbound ACEs of user 'Kinda KU. USY' in the 'ADLAB.LOCAL' domain, then extract the permissive rights granted to non-default RIDs (i.e. above 1000), or permissive groups (e.g. 'Everyone' with SID 'S-1-1-0') $DumpInboundACLs = Invoke-PassTheCert -Action 'GetInboundACEs' -LdapConnection $LdapConnection -Object 'CN=Kinda KU. USY,CN=Users,DC=ADLAB,DC=LOCAL' $DumpInboundACLs |?{ $_.AceQualifier -eq 'AccessAllowed' -and ($_.AccessMaskNames -ilike '*GenericAll*' -or $_.AccessMaskNames -ilike '*GenericWrite*' -or $_.AccessMaskNames -ilike '*WriteProperty*' -or $_.AccessMaskNames -ilike '*WriteDACL*') -and ($_.SecurityIdentifier -match 'S-1-5-21-(\d+-){3}\d{4,}' -or $_.SecurityIdentifier -match 'S-1-5-21-(\d+-){3}513' -or $_.SecurityIdentifier -match 'S-1-5-21-(\d+-){3}515' -or $_.SecurityIdentifier -in @('S-1-1-0', 'S-1-5-11', 'S-1-5-15', 'S-1-5-7', 'S-1-5-32-545', 'S-1-5-32-546')) }
:::
NetExec (Python) also has useful modules that can be used to
- map information regarding AD-CS (Active Directory Certificate Services)
- show subnets listed in AD-SS (Active Directory Sites and Services)
- list the users description
- print the Machine Account Quota domain-level attribute's value
# list PKIs/CAs
nxc ldap "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" -M adcs
# list subnets referenced in AD-SS
nxc ldap "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" -M subnets
# machine account quota
nxc ldap "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" -M maq
# users description
nxc ldap "$DC_IP" -d "$DOMAIN" -u "$USER" -p "$PASSWORD" -M get-desc-users
The PowerShell equivalent to netexec's subnets modules is the following
[System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites.Subnets