When I’m on an engagement, one of my favorite value-adds for a client is conducting an informal password audit. While most organizations have realized the importance of maintaining password standards, most overestimate how secure their users’ passwords are when they adhere to GPO rules. The present “best practice” tends to be eight characters with complexity, changed every 90 days. What many domain administrators don’t realize, however, is that a password can be technically compliant while still being highly guessable. Since most passwords change every 90 days, it’s very common to see passwords like “Summer2016” as the seasons also change every 90 days. Furthermore, even though there are four character types (upper case, lower case, number, symbols), enabling complexity in the standard password GPO only requires a password contain three of them. This usually means that special characters are treated as optional or easily predictable, such as an exclamation point at the end (“Summer2016!”).
Luckily, the tools for testing all passwords in an Active Directory are freely available. Here is a quick and dirty overview of the path that I take during engagements.
Step Zero: Preparing Your Environment
Like most people, I do most of my pentesting in a Kali VM. While Kali already comes with many common tools preinstalled, but there are some less common tools that will likely not be configured. For this method, we will be using:
- Metasploit (via msfconsole)
Installing and configuring Metasploit is beyond the scope of this article, but if you’re building a Kali install up from scratch, I would highly recommend taking a look at TrustedSec’s Penetration Testers Framework. PTF has saved me a lot of hours and headache by centralizing the installation of many tools not included in the default Kali install.
libesedb is a tool for parsing the ESE (Extensible Storage Engine) database where Active Directory data is stored. The installation/building instructions are available here, with downloads available here. libesedb requires a bit of configuration upon install, so here are the commands I used for successful install:
tar xfv libesedb-experimental-20151213.tar.gz
sudo make install
ntdsextract is an Active Directory forensics tool that is thankfully easier to install. This is the only command you’ll need:
Now while john comes with Kali, I like to add a little bit of extra oomph under the hood, so I add the KoreLogic wordlist rulesets to the existing logic. Luckily, this is a simple addition with this one-liner:
Step One: Claim What’s Yours
In order to perform password cracking, we need to extract the Active Directory database. This requires access to a domain administrator account – if you’ve compromised one during pentesting, then you’re already set, otherwise ask a sysadmin very nicely if you can borrow one. Once you’ve got your account credentials, fire up msfconsole and use auxiliary/admin/smb/psexec_ntdsgrab.
psexec_ntdsgrab is a pretty neat module. While there are other ways of extracting domain hashes from a domain controller (hashdump or smart_hashdump, for example), they generally require a remote session on a domain controller, and don’t always extract the complete Active Directory as the are pulled from cached memory. Instead, psexec_ntdsgrab locally downloads a copy of the ntds.dit and SYSTEM hive files for a complete and current snapshot of the environment. While normally the ntds.dit file cannot be remotely interacted with, psexec_command creates a Volume Shadow Copy backup on the DC and extracts the relevant files from that copy, since they are not under the same read restrictions as the main ntds.dit file.
Set the options for RHOST to point at a domain controller of your choice, and for SMBDomain, SMBUser, and SMBPass for the relevant domain administrator credentials. For this guide, I’ve stood up a test environment populated with a little over 200 fictitious users.
Once everything is ready, let it fly. Sometimes the domain controller will take longer to create a new Volume Shadow Copy than the module will wait for, so if it starts creation but does not completely download the files, simply run it again. In my experience, it very often takes two tries.
Take note of the location of the downloaded .dit and .bin files, as we will be referencing those file paths later on.
Step Two: Turning the Tables
Outside of msfconsole, you’ll want to open a terminal to whichever directory you installed libesedb and cd to esedbtools. In my case, that directory is /tools/libesedb-20151213/esedbtools. Here there is a tool called esedbexport, which will take the .dit database and export them into parseable tables. This is the command to do this:
Depending on the size of the environment, it may take a long time to export these tables, especially datatable. An environment with over 200 users took upwards of 15 minutes, so don’t fret if it seems stalled.
Once the export is complete, you will have a handful of tables in the export directory you specified. Note that the output appends .export to the directory, so if you gave it /root/Desktop/ntds like I did, the folder will actually be /root/Desktop/ntds.export.
Step Three: Make it Rain Hashes
We will now need to convert these Active Directory tables into a format that john can read. To do this, we will use dsusers.py from the ntdsextract suite. For sanity reasons, I find it easiest to cd to the .extract directory created by esedbexport and call dsusers.py from there, as we will be providing a lot of input and output directories. Here’s what the usage for dsusers.py looks like:
This command tells dsusers.py to use the datatable and the link_table to export both LM and NT hashes in a password format usable by john to the specified export directory, and requires reference to the SYSTEM hive .bin file we obtained from psexec_ntdsgrab earlier.
Running this command will fill your terminal with tons of Active Directory user data, but ultimately we’re looking for those LM and NT hash files:
Step Four: Let’s Get Cracking
Now that we have two john-friendly text files, let’s spill some secrets. The command I use has john run all rules in the ruleslist, and splits the wordlist between two processor cores for additional speed:
Depending on the strength of the passwords, you’re likely to see results almost immediately. In my experience, even if the domain users adhere to a strong password policy, many service accounts or shared mailboxes are grandfathered in with weak passwords that never expired. These can often catch even the most rigorous IT department by surprise.
john will continue cracking passwords for as long as it is allowed to run, moving on to brute force methods once all the wordlist rules have been completed. You can stop john at any time with Ctrl-C, and show the results of the cracking so far with this:
This output can be parsed down to just the usernames with a quick awk flag:
(Optional) Step Five: Sticks and Carrots
What you do with this list of users with weak and easily guessed passwords is up to you. I’ve seen clients that require remedial password security training for employees that have their passwords cracked, but I also like to encourage organizations to celebrate users that are not breached rather than just punishing those that fail. Oftentimes a simple pizza party for anybody that passed is enough incentive for employees to get the memo.
Password security is an ongoing discussion in the information security community, with length, complexity, hashing and storage methods, and multifactor considerations all highly contested. For this type of password cracking, however, I try to reduce my advice for user training down to one simple guideline:
Don’t use passwords that are a dictionary word followed by a number. Even just using two dictionary words followed by a number will significantly complicate any attempted cracking attempt.
Obviously, no password is secure once the hash has been obtained, but applying a little bit of common sense and demonstrating just how easy it is for passwords to be compromised can go a long way toward user education and overall risk reduction.
- Pentesting the Hard Way, Part One: What is a Pentest? - July 12, 2016
- Security for Everybody: Secure Your Browser - June 21, 2016
- Cracking Domain Passwords from NTDS.dit with Metasploit and john - May 3, 2016