LDAP response starts with the affected object and attribute. A read-heavy event usually means enumeration or secret access. A write event means the directory state may have changed and must be reverted precisely.
High-value events
| Event | Meaning | Focus |
|---|---|---|
| 4624 | Successful logon | LDAP bind source host, account, logon type, authentication package |
| 4625 | Failed logon | Bad binds, password guessing, broken tooling, invalid credentials |
| 4662 | Directory object operation | Sensitive attribute reads, DCSync rights use, object access where SACLs exist |
| 4720 | User created | LDAP-created account or follow-on persistence |
| 4726 | User deleted | Account removal |
| 4728 | Member added to global group | Group membership abuse |
| 4732 | Member added to local group | Local/domain local group abuse |
| 4738 | User changed | UAC, password, SPN, account metadata changes |
| 4741 | Computer account created | Machine account staging, RBCD setup |
| 4742 | Computer account changed | RBCD, SPN, delegation, DNS host name changes |
| 5136 | Directory object modified | Attribute changes such as member, servicePrincipalName, msDS-KeyCredentialLink, gPLink, unicodePwd |
| 5137 | Directory object created | New user, computer, GPO, DNS, or configuration object |
| 5139 | Directory object moved | OU staging or object relocation |
| 5141 | Directory object deleted | Deleted user, computer, GPO, or configuration object |
Fast event review
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624,4625,4662,4720,4726,4728,4732,4738,4741,4742,5136,5137,5139,5141} |
Select-Object -First 100 TimeCreated,Id,ProviderName,Message
LDAP modification hunting
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=5136} |
Where-Object {
$_.Message -match 'servicePrincipalName|msDS-KeyCredentialLink|msDS-AllowedToActOnBehalfOfOtherIdentity|unicodePwd|userAccountControl|member|gPLink|nTSecurityDescriptor'
} |
Select-Object TimeCreated,Id,Message
Sensitive read hunting
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4662} |
Where-Object {
$_.Message -match 'ms-Mcs-AdmPwd|msLAPS|msDS-ManagedPassword|Replicating Directory Changes|nTSecurityDescriptor'
} |
Select-Object TimeCreated,Id,Message
Review recent object changes
Get-ADObject -LDAPFilter '(|(objectClass=user)(objectClass=computer)(objectClass=group)(objectClass=groupPolicyContainer))' `
-Properties whenChanged,whenCreated,uSNChanged |
Sort-Object whenChanged -Descending |
Select-Object -First 50 Name,ObjectClass,DistinguishedName,whenChanged,whenCreated,uSNChanged
Review Shadow Credentials
Get-ADObject -LDAPFilter '(msDS-KeyCredentialLink=*)' -Properties msDS-KeyCredentialLink |
Select-Object Name,ObjectClass,DistinguishedName,msDS-KeyCredentialLink
Clear malicious Shadow Credentials only after preserving the original value.
Set-ADUser -Identity svc_web -Clear msDS-KeyCredentialLink
Set-ADComputer -Identity TARGETCOMPUTER -Clear msDS-KeyCredentialLink
Review RBCD changes
Get-ADComputer -Filter * -Properties msDS-AllowedToActOnBehalfOfOtherIdentity |
Where-Object { $_.'msDS-AllowedToActOnBehalfOfOtherIdentity' } |
Select-Object Name,DistinguishedName,msDS-AllowedToActOnBehalfOfOtherIdentity
Clear RBCD
Set-ADComputer -Identity TARGETCOMPUTER -Clear msDS-AllowedToActOnBehalfOfOtherIdentity
Review SPN changes
Get-ADObject -LDAPFilter '(servicePrincipalName=*)' -Properties servicePrincipalName,whenChanged |
Sort-Object whenChanged -Descending |
Select-Object -First 50 Name,ObjectClass,DistinguishedName,servicePrincipalName,whenChanged
Remove suspicious SPN
Set-ADUser -Identity svc_web -ServicePrincipalNames @{Remove='ootw/fake'}
Set-ADComputer -Identity TARGETCOMPUTER -ServicePrincipalNames @{Remove='HTTP/relay.ootw.local'}
Review group membership changes
Get-ADGroupMember "Domain Admins"
Get-ADGroupMember "ACL Operators"
Get-ADGroupMember "Workstation Admins"
Remove unauthorized group member
Remove-ADGroupMember -Identity "ACL Operators" -Members "alice.wright" -Confirm:$false
Review password reset indicators
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4723,4724,4738} |
Select-Object TimeCreated,Id,Message
Restore user account control flags after abuse
Get-ADUser svc_web -Properties userAccountControl
Set-ADUser svc_web -Replace @{userAccountControl=512}
Hardening
- Require LDAP signing and LDAP channel binding.
- Prefer LDAPS or StartTLS for credential-bearing operations.
- Restrict who can read LAPS, Windows LAPS, gMSA, deleted objects, and sensitive security descriptors.
- Audit reads of
ms-Mcs-AdmPwd,msLAPS-*,msDS-ManagedPassword, and replication rights. - Audit writes to
servicePrincipalName,member,userAccountControl,unicodePwd,msDS-KeyCredentialLink,msDS-AllowedToActOnBehalfOfOtherIdentity,gPLink, andnTSecurityDescriptor. - Review MachineAccountQuota and monitor unexpected computer account creation.
- Limit delegated rights that allow password reset, SPN write, group membership write, Shadow Credentials, RBCD, and DCSync.
- Treat LDAP write access as an execution path, not just an administrative convenience.
Notes
LDAP changes are often small but high impact. A single attribute write can create Kerberoasting, Shadow Credentials, RBCD, DCSync, GPO abuse, or direct password reset.
For cleanup, restore the exact previous attribute value when possible. Clearing an attribute blindly can break legitimate service configuration.