Extracting Password Hashes from Large NTDS.DIT Files
Recently, the Sword & Shield pentest team made its annual pilgrimage to Louisville, Kentucky, to attend one of the best InfoSec conferences in United States, DerbyCon. They were not expecting to learn about extracting password hashes from large NTDS.DIT files.
Derbycon is a conference for hands-on security professionals by hands-on security professionals. Talks range from security 101 to advanced kernel exploitation techniques.
Training plug: As a side note, one of our penetration testers took the Corelan Foundations exploit development training there and expressed this was one of the best courses he had ever taken. The course is created by corelanc0d3r and was taught by Corelan team members Lincoln and thelightcosine. Our pen tester highly recommends it if you are interested in software exploitation and exploit development.
During the conference, the team participated in the Capture-The-Flag competition, along with their good friend Stephen Haywood (Twitter: @AverageSecurityGuy). If you are not familiar with CTF events, see here or here. The penetration testing team ended up placing a reluctant eighth in the competition after they ran into a problem that was a valuable learning opportunity (the whole point of a CTF) and felt it would be valuable to share.
On the second day of the CTF, the team had obtained Domain Administrator access to the target Active Directory domain. After obtaining access to the domain controller, the members of the penetration testing team saw it was a Windows Server 2012 box. Their next steps were to extract all usernames and password hashes on the domain controller. As this was a domain controller, their safest option was to shadow copy and download the backup NTDS.dit file (where all the good stuff is). As they have done on a multitude of penetration tests, they could then run it through libesedb’s esedbexport tool to export the tables and then use NTDSextract’s dsusers.py script to pull the usernames and password hashes. If you are unfamiliar with this technique, see here or here.
The only difference this time was that before they used esedbexport, they made sure to update the tool to the most recent version (like good pen testers do). They launched their command to extract the tables and moved on to attack other boxes in scope for the CTF:
Little did they know the MAJOR mistake they had just made…
After letting the tool run all night, the penetration testing team noticed on Sunday morning with 1 hour until the CTF ended that their table file was only at 60megs and that it was only increasing about about 4k per second. That is great, except for the fact that their NTDS.dit file is around 467Megs. There was no chance we were finishing this export in time.
On Monday, once the team leader got over the frustration that the team had all the data they needed to get tons of points on their hard drive but couldn’t get to it, he began to do some testing. Something was just not right, as it took WAAAAYYY too long to only yield 60megs of data. His digging revealed they were not the only ones with this issue:
Turns out, certain versions of libesedb are SIGNIFICANTLY slower that other versions. The team lead went and grabbed the oldest version he could find from a Fedora repo here:
After building from source, this burned through the entire 467megs at a rate of about 1.5M per second. MUCH better. Once that finished, he was able to quickly dump and crack the hashes, just not in time to score points.
He also found you could just use the secretsdump.py from the impacket toolkit by the CoreSecurity Team. It takes about a total of 10 seconds for a 467meg NTDS.dit file.
Additionally, the fine folks over at Metasploit have provided a post module that will do this as well (The leader has only tested this on server 2008, though).
Turns out newer is not always better.
Lesson learned indeed.