Last updated at Tue, 22 Aug 2017 14:49:02 GMT
UPDATE: It has been pointed out that there is prior work worth noting. This blog post by Damon Cortesi talked about using Volume Shadow Copy to get the SAM file back in 2005. As with all things in our Industry, we stand on the shoulders of those who came before us. We would certainly not want to take away from anyone else's previous work and accomplishments.
Dumping the stored password hashes from a live Domain Controller can be tricky. There are a number of things to consider, and there have been several approaches over the years. Some of these approaches have had glaring problems with them. We've recently changed all that. Before we talk about our new approach, let's take a look at the history there.
The original way Metasploit dumped any Windows password hashes was through LSASS injection. LSASS(Local Security Authority Subsystem Service) is the service responsible for handling authentication and security policies on a Windows system. Meterpreter would inject into the lsass.exe process and scrape the password hashes directly out of process memory. This was effective but very dangerous. Injecting into LSASS could make the process unstable and could potentially crash it. If LSASS goes down in Windows, the whole system ends up in a bad state and will have to be rebooted to fix it. If you do this on a live Domain Controller, you are not just taking out authentication on that Domain Controller but potentially for the whole domain itself. Metasploit moved away from this approach for workstations a long time ago, abandoning it for a Registry based approach in the Hashdump post module. This remained the de facto method for getting Domain hashes however.
The NTDS.dit file is the database for Active Directory. It is an Extensible Storage Engine(ESE) Database. This is a poorly documented format that is based on the Jet Database Engine. While a Domain Controller is running, NTDS.dit is of course locked. We need a way to get a copy of the file that is not locked. Several years ago there was an article on safely dumping domain hashes. It was written by Tim Tomes about research that he and Mark Baggett had done. Their technique abuses Volume Shadow Copy Service(VSS) to make a copy of the NTDS.dit file. They then used other tools to then parse the raw file itself. Their work, and ours was based heavily on the research of Csaba Barta published in this white paper.
Running Extraction Tools on the Victim
Once we have a copy of NTDS.dit we need to parse it. The approach used by tools like ntdsxtract is to parse the file itself. If we were to run tools like this on the victim, they will suck the whole file up in memory. Parse out the user accounts, and then dump them back out somewhere. The problem with these tools is that they can greedily suck up memory and CPU cycles on the machine. You can still end up pegging the CPU on the live Domain Controller. As a PenTester your client will not be too happy if you grind their DC to a halt. If you are doing a true Red Team type exercise, this also greatly increases the chance that you'll get caught. There are definitely some issues with this approach as well.
Another option that people use, is to download the copy of the NTDS.dit file, and the pieces of the Registry that they will need to decrypt the stored hashes. They can then feed those pieces into offline tools on their own box, and not worry about consuming target resources. The glaring problem with this approach arises in larger organizations. NTDS.dit can grow to be GB in size. Transferring a file that big will take time. It is likely to attract notice, and if your connection to the target is lost in the middle, you have nothing usable for your trouble. This is still not an ideal scenario.
Meterpreter to the rescue!
Remember when I told you that NTDS.dit is an ESE Database? ESE is based on the Jet Engine. The Domain controller must have some way of accessing NTDS.dit that does not involve reading it as a raw file right? Well, every Windows system comes with the JetAPI. We can use the JetAPI to have Windows handle all the database parsing for us. We create a Jet Engine Instance, and attach it to our copy of the NTDS database. We can then step through the database and find the specific records for valid user accounts. This allows us to do all our parsing on the target, but without loading the entire file into memory at once.
When Meterpreter attaches to the database, it creates a Channel back to the Metasploit client. This channel acts as a pipe directly to the parser. Our client is then able to perform read operations on this channel. Every time a read operation is triggered, the parser will pull out up to 20 user accounts and send them back over the wire. Batching the accounts this way serves multiple purposes. It keeps our memory usage low as we only have 20 accounts loaded into memory at a time. It keeps our request/response windows somewhat efficient, which is important for HTTP based session transport. Most importantly, it means that we are pulling accounts in real time. If our connectivity is lost, or the session dies, we have not lost all progress. We still end up with the accounts we managed to get to at that point.
The User Accounts
The NTDS user account objects we get back contain a lot of information about those accounts. Let's take a look at what we get from each account:
- The Account Name (samAccountname)
- The account Description
- The Date and Time of the last time the account logged in
- The Date and Time of the last time the account's password was changed
- The Date of when the current account password expires
- If the Account is Disabled
- If the Account is locked out
- If the Account's password has expired
- If the Account's password is set to never expire
- The current NT and LM hashes for the account
- The saved history of previous NT and LM hashes (up to 20 depending on AD settings)
Make a special note of that last one. Not only are we dumping the current NTLM hashes for each account. We're dumping all the password hashes going back up to 20 previous passwords. If you crack all of these hashes, you'll be able to even do trending data on the passwords. Does a particular user just use the same password with an incrementing number? Well you'll know what his next password is. Do you see “changeme123” or “summer2015” in a lot of user's histories? Then you probably have the IT helpdesk's password reset scheme. There are a lot of ways this historical data can benefit of a PenTester, and we won't take the time to go into all of them here. Just use your imagination.
The current and historical hashes will be saved as NTLMHash Credential objects in the database. From here you can crack those hashes with Metasploit's John the Ripper integration, using auxiliary/analyze/jtr_crack_fast. If you don't want to crack them you can always use them for pass the hash attacks using our Bruteforcers/Psexec mdoules. Metasploit Pro users will be able to immediately use those credentials in the Credential Reuse part of the app, or the Pass the Hash Metamodule.
No longer will you have to reach for another tool when you get a session on a Domain Controller. Just reach for the new post module at post/windows/gather/credentials/domain_hashdump. It will take care of all the rest for you. Happy pwning!
[ETA] If you'd like a video explainer of how to safely dump Active Directory password hashes with Meterpreter, we have one right here.