AD Dynamic Objects (dynamicObject) Anti-Forensics
Mechanics & Detection Basics
- Any object created with the auxiliary class
dynamicObjectgainsentryTTL(seconds countdown) andmsDS-Entry-Time-To-Die(absolute expiry). WhenentryTTLreaches 0 the Garbage Collector deletes it without tombstone/recycle-bin, erasing creator/timestamps and blocking recovery. entryTTLis an operational/constructed attribute: request it explicitly in LDAP queries. TTL can be refreshed either by updatingentryTTLbefore expiry or via LDAP TTL refresh OID1.3.6.1.4.1.1466.101.119.1.- TTL min/default are enforced in Configuration\Services\NTDS Settings →
msDS-Other-Settings→DynamicObjectMinTTL/DynamicObjectDefaultTTL. Microsoft documents 86400s as the default TTL and 900s as the default minimum valid TTL; both support 1s–1y. Dynamic objects are unsupported in Configuration/Schema partitions. - There is no static→dynamic conversion and no tombstone phase after expiry. IR teams cannot rely on deleted-object controls or Recycle Bin; they must capture the live object/metadata before GC removes it.
- Refresh is replica-sensitive: if TTL is renewed too close to expiry, another writable replica or GC can still delete the object locally before the refresh replicates. Very short TTLs therefore work best when the attacker knows which DC will service the abuse, while defenders should query all naming contexts / replicas during triage.
- Deletion can lag a few minutes on DCs with short uptime (<24h), leaving a narrow response window to query/backup attributes. Detect by alerting on new objects carrying
entryTTL/msDS-Entry-Time-To-Dieand correlating with orphan SIDs/broken links.
Fast Enumeration / Live Triage
- Query all
namingContextsfrom RootDSE, not only the domain NC. Dynamic abuse can live inDomainDnsZones/ForestDnsZones(dnsNode) or in application partitions. - While the object is still alive, immediately dump replication metadata and any linked attributes/ACLs. After expiry you may be left only with broken
gPLinkvalues, orphan SIDs, or cached DNS answers.
$root = Get-ADRootDSE
$root.namingContexts | ForEach-Object {
Get-ADObject -LDAPFilter '(objectClass=dynamicObject)' -SearchBase $_ `
-Properties entryTTL,msDS-Entry-Time-To-Die,gPCFileSysPath,msDS-CreatorSID |
Select-Object DistinguishedName,entryTTL,msDS-Entry-Time-To-Die,gPCFileSysPath,msDS-CreatorSID
}
repadmin /showobjmeta <DC> <distinguishedName>
MAQ Evasion with Self-Deleting Computers
- Default
ms-DS-MachineAccountQuota= 10 lets any authenticated user create computers. AdddynamicObjectduring creation to have the computer self-delete and free the quota slot while wiping evidence. - Powermad tweak inside
New-MachineAccount(objectClass list):$request.Attributes.Add((New-Object "System.DirectoryServices.Protocols.DirectoryAttribute" -ArgumentList "objectClass", "dynamicObject", "Computer")) > $null - If the requested TTL is below
DynamicObjectMinTTL, expect server-side adjustment or rejection depending on the creation path; in many domains the effective floor is 900s and the fallback/default remains 86400s. ADUC may hideentryTTL, but LDP/LDAP queries reveal it. - While the object exists, defenders can still recover the unprivileged creator from
msDS-CreatorSIDon the computer object. Once the dynamic computer expires, that attribution disappears with the object.
Stealth Primary Group Membership
- Create a dynamic security group, then set a user’s
primaryGroupIDto that group’s RID to gain effective membership that doesn’t show inmemberOfbut is honored in Kerberos/access tokens. - TTL expiry deletes the group despite primary-group delete protection, leaving the user with a corrupted
primaryGroupIDpointing to a non-existent RID and no tombstone to investigate how the privilege was granted. - Reporting is tool-dependent:
Get-ADGroupMember/net groupusually resolve primary-group-derived membership, whilememberOfandGet-ADGroup -Properties memberdo not. For broaderprimaryGroupIDtradecraft, see this other page about DCShadow and PGID abuse. - For non-AdminSDHolder-protected targets, attackers can pair the dynamic-group trick with a DACL deny on reading
primaryGroupID(or the groupmemberattribute) to hide the link from many LDAP/PowerShell workflows even before the group expires.
AdminSDHolder Orphan-SID Pollution
- Add ACEs for a short-lived dynamic user/group to
CN=AdminSDHolder,CN=System,.... After TTL expiry the SID becomes unresolvable (“Unknown SID”) in the template ACL, and SDProp (~60 min) propagates that orphan SID across all protected Tier-0 objects. - Forensics lose attribution because the principal is gone (no deleted-object DN). Monitor for new dynamic principals + sudden orphan SIDs on AdminSDHolder/privileged ACLs.
Dynamic GPO Execution with Self-Destructing Evidence
- Create a dynamic
groupPolicyContainerobject with a maliciousgPCFileSysPath(e.g., SMB share à la GPODDITY) and link it viagPLinkto a target OU. - Clients process the policy and pull content from attacker SMB. When TTL expires, the GPO object (and
gPCFileSysPath) vanishes; only a brokengPLinkGUID remains, removing LDAP evidence of the executed payload. - This is operationally cleaner than classic GPODDITY-style cleanup: instead of restoring the original
gPCFileSysPathyourself, AD removes the malicious GPC automatically once the timer expires.
Ephemeral AD-Integrated DNS Redirection
- AD DNS records are
dnsNodeobjects in DomainDnsZones/ForestDnsZones. Creating them as dynamic objects allows temporary host redirection (credential capture/MITM). Clients cache the malicious A/AAAA response; the record later self-deletes so the zone looks clean (DNS Manager may need zone reload to refresh view). - Detection: alert on any DNS record carrying
dynamicObject/entryTTLvia replication/event logs; transient records rarely appear in standard DNS logs.
Hybrid Entra ID Delta-Sync Gap (Note)
- Entra Connect delta sync relies on tombstones to detect deletes. A dynamic on-prem user can sync to Entra ID, expire, and delete without tombstone—delta sync won’t remove the cloud account, leaving an orphaned active Entra user until an initial/full sync or manual cloud cleanup is forced.