A potential bad actor’s full network penetration repertoire is beyond the scope of this article. Here, we’re looking at the scenario where elevated domain access has been gained by the hacker. What would be an obvious next step for this player to consider? The answer is stored somewhere inside the Ntds.dit database.

All passwords of users and computers, system objects, and group memberships are stored inside the Ntds.dit file. Hence, this is the key to the kingdom. Non-security disciplined personnel may try to simply copy this file using Windows GUI. That’s the wrong way because this is a database file that is in constant read-write locking mode by the system’s, “Kerberos Key Distribution Center,” services. These are some of the the methods to retrieve a copy of this file.

Method 1: Use an Advanced Windows Penetration tool such as PowerSploit (https://github.com/PowerShellMafia/PowerSploit)

If this module is imported, it has a function called Invoke-NinjaCopy. Yup, it’s does what its name implies. The magic is in the module’s ability to evade the System services to record any activities; hence, there would be no triggering of monitoring systems. The way Invoke-NinjaCopy accomplishs this is by accessing NTFS-partitioned raw volume I/O abstracted by the PowerShell’s Invoke-MemoryLoadLibrary.

Command: Invoke-NinjaCopy -path C:\Windows\NTDS\ntds.dit -localdestination C:\Extract\SYS\ntds.dit

Method 2: Use the Novice plain vanilla PowerShell commands

vssadmin create shadow /for=c:
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy$version\Windows\ntds\ntds.dit
reg SAVE HKLM\SYSTEM C:\Extract\SYS
\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy$version\Windows\System32\config\SYSTEM C:\Extract\SYSTEM
vssadmin delete shadows /shadow=$shadowID

Now that a point-in-time NTDS.DIT has been copied, the next step is to extract password hashes and record system object IDs (beyond the scope of this writing). This process can run on any computer: Windows, Linux, or MacOS.

The advanced method is to continue using tools such as PowerSploit. There’s a function called Invoke-Mimikatz that “leverages Mimikatz 2.0 and Invoke-ReflectivePEInjection to reflectively load Mimikatz completely in memory. This allows you to do things such as dump credentials without ever writing the Mimikatz binary to disk.”

Commands:
Invoke-Mimikatz -DumpCreds $LSASSHash

LSADUMP::LSA – Ask LSA Server to retrieve SAM/AD enterprise (normal, patch on the fly or inject). Use to dump all Active Directory domain credentials from a Domain Controller or lsass.dmp dump file. Also used to get specific account credential such as krbtgt with the parameter /name: “/name:krbtgt”

LSADUMP::DCSync – ask a DC to synchronize an object (get password data for account).

LSADUMP::SAM – get the SysKey to decrypt SAM entries (from registry or hive). The SAM option connects to the local Security Account Manager (SAM) database and dumps credentials for local accounts. This is used to dump all local credentials on a Windows computer.

LSADUMP::Trust – Ask LSA Server to retrieve Trust Auth Information (normal or patch on the fly). Dumps trust keys (passwords) for all associated trusts (domain/forest).

Once more, it’s worth a mention that a novice approach is to use Windows. There is a PowerShell module called DSInternals that has a function named Get-ADDBAccount to perform passwords extraction. Note that there is a $key variable that I can’t show you here as somebody may violate a company’s security policies, under the “no system penetration testing without authorization” clause.

Command:
Import-Module DSInternals
Get-ADDBAccount -All -DBPath ‘C:\Extract\ntds.dit’ -BootKey $key

Note that this method only retrieves “password hashes,” not the plain-text values. Here are more DSInternals commands to illustrate follow-through:

# Decrypt a password from Group Policy Preferences
ConvertFrom-GPPrefPassword $groupPolicyPrefPassword

# Decrypt a password from Password Blob
ConvertFrom-ADManagedPasswordBlob $ADManagedPasswordBlog

# Decrypt a password from an unattend.xml file
ConvertFrom-UnattendXmlPassword $unattendXmlPassword