Lil Pwny – Auditing Active Directory passwords using multiprocessing in Python

This post is partially out of date, and should be read in combination with the version 2.0.0 release notes

About

Lil Pwny is an application I created to check passwords from Active Directory against the list of compromised passwords from Have I Been Pwned, the collection of real world passwords previously exposed in data breaches.

Lil Pwny running with test data

It was created out of a need to audit the strength of passwords in an Active Directory environment against not only known compromised credentials, but against a list of user provided credentials, in my case, this was a list of passwords commonly known to be used in my company, as well as ones that contained the companies name.

Another feature is the ability to check for accounts using the same passwords. With this I am looking for two things:

  • Multiple service accounts using the same passwords, indicating an admin user reusing a single password when creating accounts and not changing it.
  • Admin users using the same password for their standard and elevated privileges accounts.

This can be a powerful tool for carrying out a one off audit of the state of passwords being used in an environment. From the blue team side of things, it is even more powerful when automated to run regularly and combined with education for the users who return compromised passwords. After all, this data is useless until you do something with it.

Resources Required

The current HIBP password list contains over 550 million passwords (555,278,657 to be precise). There is no escaping that comparing against all of these passwords is going to be resource hungry, especially when you are exporting a large amount of users from Active Directory.

Every effort has been made for Lil Pwny to run as quickly as possible, while still being written in Python. This is mainly by using multiprocessing, and by loading the HIBP password list into memory for faster indexing.

Lil Pwny splits the list of AD user hashes into equal-sized chunks of number of cores - 1, leaving one core to handle the list shared across processes . A process is then created for each of these cores to search their chunk of the AD user hash list against the HIBP hash list

How multiprocessing is used to increase auditing speed

These optimisations mean that the higher-spec hardware you are using, the faster the audit will run. I have run this in production using a GCP Compute Engine host with 80 cores and 80GB RAM. With these specs I was able to compare ~6800 users against the HIBP list in 48 minutes. Lil Pwny will run on a lower spec machine, it will just take longer.

Installation

Lil Pwny is available on PyPI, so installation is as simple as:

pip install lil-pwny

If you want to build it from source, you can find it on GitHub: https://github.com/PaperMtn/lil-pwny/releases 

In the next part, I will dive deeper into recovering passwords from Active Directory.