ADTRADE-003: Stale BitLocker Recovery Keys
- Plataforma
- Active Directory
- Categoría
- AD Adversary Tradecraft Indicators
- Severidad
- Medium
- Pilar de Zero Trust
- Visibility & Analytics (peso 1)
- Fixtures de referencia
- 3
- Cobertura de ramas
- Observada: los fixtures prueban los veredictos que ejercitan
- Procedencia
- baseline
Qué comprueba
The check performs an LDAP query for (objectClass=msFVE-RecoveryInformation) across every domain partition, returning the distinguishedName, whenCreated, and msFVE-RecoveryGuid of each object. The parent DN of every result (the computer object that owns the recovery record) is resolved and inspected for three signal attributes: userAccountControl (to detect ACCOUNTDISABLE bit 0x0002), lastLogonTimestamp (replicated; treated as stale when older than 90 days), and operatingSystem / operatingSystemVersion (to surface end-of-life Windows builds whose physical drives are most likely already in disposal pipelines). The check also reads the nTSecurityDescriptor on the msFVE-RecoveryInformation objects and on the parent computer to list any principal granted the BitLocker recovery extended right (control access right msFVE-RecoveryGuid, GUID ffa6f046-ca4b-4feb-b40d-04dfee722543) or generic read on the FVE attributes. A finding is raised for every recovery object whose parent is disabled, whose parent has lastLogonTimestamp older than 90 days, or whose parent is missing entirely (orphaned msFVE record under a tombstoned computer). The check additionally surfaces recovery passwords older than 365 days even when the parent is active, since stale keys typically indicate the drive was never re-encrypted after a TPM clear or motherboard swap.
Por qué importa
Recovery passwords in AD are not credentials to a running service: they are the master decryption material for a physical volume. The blast radius is bounded by who can read the FVE attributes, not who can log on to the device. In a default forest, members of Domain Admins and the delegated BitLocker recovery group can extract any recovery password by walking the msFVE-RecoveryInformation tree, and in most enterprises that group is wider than Tier 0 (help desk, deskside support, an IT operations service account, sometimes the entire Server Operators group through inherited permissions). Microsoft documents that AD retains the full history of recovery passwords for a computer object and does not prune old keys automatically: every TPM clear, every motherboard replacement, every re-encryption event adds a new msFVE-RecoveryInformation child but the old child stays. When the physical drive leaves the building (asset disposal, theft, accidental loss), the recovery key needed to decrypt it offline is still sitting in AD long after the computer has been removed from operational inventory. An attacker who breaches the help-desk tier (a far softer target than Tier 0) can query the entire historical recovery-key set and combine it with any drive they can physically recover. The exposure is not theoretical: drive resale from refurbishers, dumpster-recovered laptops, and stolen-asset recovery operations all create the inbound side of this attack.
Ruta de ataque
Step 1: Credential acquisition at the recovery-rights tier. The attacker compromises any account that has been delegated read access to BitLocker recovery information. In typical enterprises this is the help-desk group, a level-2 support group, or an asset-management service account, not Domain Admin. Sean Metcalf documents that the recommended Microsoft delegation pattern often results in entire help-desk OUs holding this right. Step 2: Enumeration. Using LDAP the attacker queries (objectClass=msFVE-RecoveryInformation) across the domain. Tools include Get-ADObject -LDAPFilter "(objectClass=msFVE-RecoveryInformation)" -Properties msFVE-RecoveryPassword, or ldapsearch, or PowerView Get-DomainObject. The attacker pulls msFVE-RecoveryPassword (the 48-digit numeric key) and msFVE-RecoveryGuid for every record. Step 3: Inventory correlation. The attacker cross-references the recovery records against the asset-disposal pipeline. Three high-value sources: (a) drives bought from corporate-asset refurbishers (eBay, GovDeals, ITAD partners), (b) drives recovered from facility e-waste, (c) drives in physical evidence from theft. Each drive contains a BitLocker volume header identifying its msFVE-VolumeGuid; the attacker matches that GUID against the harvested msFVE-RecoveryGuid set. Step 4: Offline decryption. The attacker connects the recovered drive to a forensic workstation and runs manage-bde.exe -unlock E: -RecoveryPassword <48-digit>. The volume mounts. All data the previous user stored (cached credentials in DPAPI, browser-saved passwords, internal documents, source code, SSH private keys, KeePass databases) is recoverable. Step 5: Lateral pivot. Cached domain credentials inside the recovered DPAPI store are decryptable offline using the user master key, also stored on the same volume. The attacker now has live domain credentials drawn from a drive that was supposedly destroyed. The attack chain depends on stale msFVE records persisting in AD after the physical hardware has left the perimeter. ADTRADE-003 closes the timing window by surfacing the orphaned records before the matching drive surfaces externally.
Cómo lo evalúa Guerrilla
Guerrilla binds to each domain naming context and issues an LDAP query: (&(objectClass=msFVE-RecoveryInformation)). For each returned object it captures distinguishedName, whenCreated, msFVE-RecoveryGuid, msFVE-VolumeGuid, and nTSecurityDescriptor. The check derives the parent computer DN by trimming the leading RDN and resolves the parent over LDAP with attribute set userAccountControl, lastLogonTimestamp, operatingSystem, operatingSystemVersion, pwdLastSet, and whenChanged. Three failure conditions raise a finding: (1) the parent computer has the ACCOUNTDISABLE bit set in userAccountControl, (2) the parent computer lastLogonTimestamp converts to a date older than the staleness threshold (default 90 days, configurable), (3) the parent computer lookup returns "No such object" indicating the record is orphaned under a deleted tombstone. The check also flags any individual msFVE-RecoveryInformation whose whenCreated is older than 365 days even when the parent is active, since long-lived recovery keys indicate the BitLocker volume has not been re-keyed since a hardware event. The nTSecurityDescriptor on each parent is parsed to enumerate every principal that holds the BitLocker recovery extended right (CAR GUID ffa6f046-ca4b-4feb-b40d-04dfee722543) or generic read on the msFVE-RecoveryPassword attribute, and the output names every non-default principal so the operator can audit the recovery group membership.
Valor recomendado
All msFVE-RecoveryInformation objects belong to computers active in the last 90 days. No keys orphaned to disabled or recently-modified-then-stale computer accounts.
Remediación
Enumerate recovery information: Get-ADObject -Filter {objectClass -eq 'msFVE-RecoveryInformation'} -Properties whenCreated. For each, walk up to the parent computer object and check its lastLogonTimestamp / Enabled. For computers inactive >90 days: confirm the drive has been wiped or destroyed, then delete the AD computer object (which cascades the recovery info). For computers actively in use but with very old recovery keys: rotate via Backup-BitLockerKeyProtector. Verify that the BitLocker recovery group has tight membership.
Veredictos probados con fixtures
Cada veredicto de esta tabla está probado por un fixture de referencia en la suite de pruebas que valida el módulo. La tabla se deriva de la última ejecución en verde; no puede editarse a mano.
| Escenario | Veredicto esperado |
|---|---|
| clean | PASS |
| known-bad | WARN |
| throttled | Not Assessed |
Mapeos a marcos de referencia
- NIST SP 800-53
- AC-6, MP-6
- CIS AD Benchmark
- 10.3.1
- MITRE ATT&CK
- T1552