hashstat: Turning a Raw NTDS Dump Into a Report

So you've compromised an Active Directory environment, owned the domain controller, and dumped the NTDS.dit. Look how cool you are. Now what?

Because what you're staring at is a wall of hashes:

corp.acme.com\john.doe:1104:aad3b435b51404eeaad3b435b51404ee:5f4dcc3b5aa765d61d8327deb882cf99:::

That line tells you john.doe has an account and no LM hash stored. It doesn't tell you if the account is enabled, if he's a domain admin, or if his password is any good. The one thing you can pull out yourself is reuse: NTLM isn't salted, we don't use salts here people, so the same password makes the same NT hash. Grep it across the dump and you've found everyone who shares it.

Everything else has to be enriched. So I built hashstat to do all of it in one pass.

hashstat demo
hashstat demo

What it does

Point it at a pwdump or secretsdump file. It's a single Python file, zero dependencies, so copy it and run it:

./hashstat.py ntds.dit -a

Feed it your John or hashcat results and it folds in the cracked plaintext. Feed it a BloodHound export and it tags every account enabled/disabled, admin, kerberoastable, and password age. Disabled accounts drop off your reset list by default (they're a delete-list, not a reset-list) but nothing gets filtered at collection time, so you keep the whole picture.

The census, run against the bundled synthetic sample:

══ OVERVIEW
  User accounts                       5,004
    analyzed (enabled)                4,381
    excluded (disabled)                 623
  using LM hash                     2,248   (51%)
  Reusing a password                    583
  Cracked (weak)                      4,381
  AFFECTED (reuse or weak)            4,381  (100%)

I lead the report with the privileged reuse. Run it with -s so it's safe to screenshot:

══ SECURITY STORY  privileged & tier-crossing reuse

  ▸ Admin reusing their OWN password on a standard account
      · a_john.doe  ↔  john.doe   [pw: <pw-23·6ch>]

  ▸ Service accounts sharing a password
      · svc_reporting  shares with 1 other acct(s)   [pw: <pw-28·11ch>]

Every list (-u reset hand-off, -D delete list, cracked, LM) exports to CSV, and -s swaps every password and hash for a stable alias so a screenshot proves who shares a secret without leaking it.

Try it

The repo ships a fully synthetic ACME dataset, so you can try every feature offline without touching real credentials:

./hashstat.py sample/ntds.dit.sample -a \
  --potfile sample/ntds.dit.sample.pot \
  --bloodhound sample

Grab it from GitHub. One file, standard library, no dependencies.

by Leon Johnson