<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: auditing-directory-service-security
description: >-
  Audit Active Directory and Azure AD directory service security including
  domain controller hardening, LDAP signing enforcement, NTLM restriction,
  Group Policy security, Kerberos configuration, AD certificate services,
  and directory replication security.
domain: cybersecurity
subdomain: identity-access-management
tags:
  - active-directory
  - azure-ad
  - domain-controller
  - ldap
  - kerberos
  - group-policy
  - ntlm
  - ad-cs
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1087.002"]
---

# Auditing Directory Service Security

## Overview

Active Directory is the backbone of enterprise identity — and the primary target
for attackers seeking domain dominance. Directory service security encompasses
domain controller hardening, authentication protocol configuration (Kerberos,
NTLM, LDAP), certificate services (AD CS), Group Policy security, replication
integrity, and Azure AD Connect synchronization security. A single misconfigured
GPO or ADCS template can provide domain-wide compromise.

Mode: `[MODE: BLUE]` for hardening audit; `[MODE: RED]` for AD attack path assessment.

MITRE ATT&CK: T1484.001 (Group Policy Modification), T1558 (Steal or Forge Kerberos Tickets), T1003.006 (DCSync)

## Prerequisites

- Domain Admin or equivalent for AD audit (read access sufficient for most checks)
- Azure AD Global Reader for hybrid configurations
- RSAT tools (Active Directory, Group Policy, DNS)
- PingCastle or Purple Knight for automated assessment
- Python 3.10+ for agent tooling

## Key Concepts

### AD Security Assessment Areas

| Area | Risk | Common Misconfigurations |
|------|------|--------------------------|
| Domain Controllers | Critical | Unpatched, unnecessary services, weak admin |
| LDAP Security | High | Unsigned LDAP, clear-text LDAP binds |
| Kerberos Config | Critical | Unconstrained delegation, weak encryption |
| NTLM Usage | High | NTLMv1 enabled, no NTLM audit/restriction |
| AD CS (PKI) | Critical | Misconfigured templates (ESC1-ESC8) |
| Group Policy | High | GPO permissions, preference passwords |
| Replication | Critical | Unmonitored DCSync-capable accounts |

### Domain Controller Hardening

```powershell
# Check DC patch level
Get-ADDomainController -Filter * |
  Select-Object Name, OperatingSystem, OperatingSystemVersion,
    @{N="LastReboot"; E={(Get-CimInstance -ComputerName $_.Name -ClassName Win32_OperatingSystem).LastBootUpTime}}

# Verify LDAP signing requirements
# Registry: HKLM\System\CurrentControlSet\Services\NTDS\Parameters
Get-ADDomainController -Filter * | ForEach-Object {
    $dc = $_.Name
    $signing = Invoke-Command -ComputerName $dc -ScriptBlock {
        Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters" `
            -Name "LDAPServerIntegrity" -ErrorAction SilentlyContinue
    }
    [PSCustomObject]@{
        DC = $dc
        LDAPSigning = switch ($signing.LDAPServerIntegrity) {
            0 { "None (VULNERABLE)" }
            1 { "Require signing" }
            2 { "Require signing" }
            default { "Not configured (VULNERABLE)" }
        }
    }
}

# Check LDAP channel binding
Get-ADDomainController -Filter * | ForEach-Object {
    $dc = $_.Name
    $binding = Invoke-Command -ComputerName $dc -ScriptBlock {
        Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters" `
            -Name "LdapEnforceChannelBinding" -ErrorAction SilentlyContinue
    }
    [PSCustomObject]@{
        DC = $dc
        ChannelBinding = switch ($binding.LdapEnforceChannelBinding) {
            0 { "Never (VULNERABLE)" }
            1 { "When supported" }
            2 { "Always (REQUIRED)" }
            default { "Not configured (VULNERABLE)" }
        }
    }
}
```

### Kerberos Security Audit

```powershell
# Find accounts with unconstrained delegation
Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation |
  Select-Object Name, DNSHostName, TrustedForDelegation

Get-ADUser -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation |
  Select-Object SamAccountName, TrustedForDelegation

# Find accounts with constrained delegation
Get-ADObject -Filter {msDS-AllowedToDelegateTo -like '*'} `
  -Properties msDS-AllowedToDelegateTo, userAccountControl |
  Select-Object Name, @{N="DelegateTo"; E={$_.'msDS-AllowedToDelegateTo'}}

# Check for Kerberoastable accounts (SPNs on user accounts)
Get-ADUser -Filter {ServicePrincipalName -like '*'} `
  -Properties ServicePrincipalName, PasswordLastSet |
  Select-Object SamAccountName, ServicePrincipalName, PasswordLastSet

# Check DES/RC4 encryption types
Get-ADUser -Filter {msDS-SupportedEncryptionTypes -band 0x7} `
  -Properties msDS-SupportedEncryptionTypes |
  Select-Object SamAccountName, @{N="EncTypes"; E={$_.'msDS-SupportedEncryptionTypes'}}
```

### NTLM Restriction Audit

```powershell
# Check NTLM audit policy
Get-ADDomainController -Filter * | ForEach-Object {
    Invoke-Command -ComputerName $_.Name -ScriptBlock {
        Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" `
            -Name "LmCompatibilityLevel" -ErrorAction SilentlyContinue |
          Select-Object @{N="DC"; E={$env:COMPUTERNAME}}, LmCompatibilityLevel
    }
}
# Level 5 = Send NTLMv2 response only, refuse LM & NTLM (REQUIRED)

# Query NTLM authentication events
Get-WinEvent -FilterHashtable @{
    LogName='Microsoft-Windows-NTLM/Operational'; Id=8001,8002,8003,8004
} -MaxEvents 100 | Select-Object TimeCreated, Id, Message
```

### AD Certificate Services (AD CS) Audit

```powershell
# List certificate templates with dangerous configurations
# ESC1: SAN allowed + Client Auth + Enrollee supplies subject
certutil -v -dstemplate | Select-String -Pattern "msPKI-Certificate-Name-Flag|pKIExtendedKeyUsage|msPKI-Enrollment-Flag"

# Find templates allowing low-privilege enrollment
Get-ADObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,$(Get-ADDomain | Select-Object -ExpandProperty DistinguishedName)" `
  -Filter {objectClass -eq 'pKICertificateTemplate'} `
  -Properties msPKI-Certificate-Name-Flag, pKIExtendedKeyUsage |
  Where-Object { $_.'msPKI-Certificate-Name-Flag' -band 1 } |
  Select-Object Name, @{N="SAN"; E={$_.'msPKI-Certificate-Name-Flag'}}

# Check for Certipy/Certify-detectable misconfigs
# certipy find -u user@domain -p password -dc-ip DC_IP -vulnerable
```

### Group Policy Security

```powershell
# Find GPOs with preference passwords (MS14-025)
Get-GPO -All | ForEach-Object {
    $gpoId = $_.Id
    $gpoName = $_.DisplayName
    $xmlPath = "\\$(Get-ADDomain | Select-Object -ExpandProperty DNSRoot)\SYSVOL\*\Policies\{$gpoId}\*\Preferences\*\*.xml"
    Get-ChildItem -Path $xmlPath -Recurse -ErrorAction SilentlyContinue |
      Select-String -Pattern "cpassword" | ForEach-Object {
        [PSCustomObject]@{
            GPO = $gpoName
            File = $_.Path
            Line = $_.Line
        }
    }
}

# Check GPO permissions — who can modify
Get-GPO -All | ForEach-Object {
    $gpo = $_
    Get-GPPermission -Guid $gpo.Id -All | Where-Object {
        $_.Permission -match "Edit|Create|Write" -and
        $_.Trustee.Name -notmatch "Domain Admins|Enterprise Admins|SYSTEM"
    } | ForEach-Object {
        [PSCustomObject]@{
            GPO = $gpo.DisplayName
            Trustee = $_.Trustee.Name
            Permission = $_.Permission
        }
    }
}
```

## Workflow

1. **Assess** — Run PingCastle/Purple Knight for baseline security score
2. **Audit DCs** — Verify patching, LDAP signing, channel binding on all DCs
3. **Review Kerberos** — Eliminate unconstrained delegation, audit SPNs
4. **Restrict NTLM** — Enable audit mode, then restrict NTLMv1
5. **Audit AD CS** — Check certificate templates for ESC1-ESC8 vulnerabilities
6. **Review GPOs** — Remove preference passwords, audit GPO permissions
7. **Monitor** — Deploy detection for DCSync, DCShadow, and admin changes

## Detection

```yaml
title: Auditing Directory Service Security Detection
id: 88408420-9bb4-47e3-a3c9-3738938d9609
status: experimental
description: Detects suspicious activity related to auditing directory service security techniques in identity access management context
logsource:
  category: authentication
  product: windows
detection:
  selection:
    EventType: authentication
    Status: failure
  condition: selection
level: medium
tags:
  - attack.t1087.002
  - attack.credential_access
falsepositives:
  - Automated password rotation by privileged access management tools
```

## Verification

- [ ] LDAP signing required on all domain controllers (LDAPServerIntegrity = 2)
- [ ] LDAP channel binding enforced (LdapEnforceChannelBinding = 2)
- [ ] No unconstrained delegation on non-DC accounts
- [ ] Kerberoastable accounts have 25+ character passwords rotated annually
- [ ] NTLMv1 disabled (LmCompatibilityLevel = 5 on all DCs)
- [ ] No GPO preference passwords (MS14-025 remediated)
- [ ] AD CS templates reviewed — no ESC1/ESC2/ESC3 misconfigurations
- [ ] DCSync-capable accounts limited to Domain Controllers + authorized

## References

- [Microsoft — AD Security Best Practices](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/)
- [PingCastle — AD Security Assessment](https://www.pingcastle.com/)
- [SpecterOps — Certified Pre-Owned (AD CS)](https://posts.specterops.io/certified-pre-owned-d95910965cd2)
- [CIS Microsoft Windows Server Benchmark](https://www.cisecurity.org/benchmark/microsoft_windows_server)
- [MITRE ATT&CK T1558](https://attack.mitre.org/techniques/T1558/)
