lil-pwny


Namelil-pwny JSON
Version 3.2.0 PyPI version JSON
download
home_pageNone
SummaryFast offline auditing of Active Directory passwords using Python and multiprocessing
upload_time2024-08-14 19:15:00
maintainerNone
docs_urlNone
authorPaperMtn
requires_python>=3.11
licenseGPL-3.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <img src="https://i.imgur.com/Q0pPSjN.png" width="450">

# Lil Pwny
![Python 2.7 and 3 compatible](https://img.shields.io/pypi/pyversions/lil-pwny)
![PyPI version](https://img.shields.io/pypi/v/lil-pwny.svg)
![License: MIT](https://img.shields.io/pypi/l/lil-pwny.svg)

Fast offline auditing of Active Directory passwords using Python.

## About Lil Pwny
Lil Pwny is a Python application to perform an offline audit of NTLM hashes of users' passwords, recovered from Active Directory, against known compromised passwords from Have I Been Pwned. Results will be output in JSON format containing the username, matching hash (can be obfuscated), and how many times the matching password has been seen in HIBP

More information about Lil Pwny can be found [on my blog](https://papermtn.co.uk/category/tools/lil-pwny/)

## Features

- **Custom Password Auditing**: Ability to provide a list of your own custom passwords to check AD users against. This allows you to check user passwords against passwords relevant to your organisation that you suspect people might be using. 
  - Pass a .txt file with the plaintext passwords you want to search for, these are then NTLM hashed and AD hashes are then compared with this as well as the HIBP hashes.
- **Detect Duplicates**: Return a list of accounts using the same passwords. Useful for finding users using the same password for their administrative and standard accounts.
- **Username as Password**: Detect users that are using their username, or variations of it, as their password.
- **Obfuscated Output**: Obfuscate hashes in output, for if you don't want to handle or store live user NTLM hashes.

### Custom Password List Enhancement
Lil Pwny provides the functionality to enhance your custom password list by adding commonly used variants of your custom passwords. These include:
- Passwords with common 'leetspeak' substitutions (e.g. `P@ssw0rd`)
- Uppercase versions of the password, and uppercase first characters (e.g. `PASSWORD`, `Password`)
- Passwords with common special characters appended or prepended (e.g. `password!`, `!password`)
- Passwords padded with common alphanumeric characters, special characters and repetitions of themselves to make them meet a given minimum length (e.g. `password123!`, `!passwordabc`, `passwordpassword`)
  - You pass your desired minimum password length to Lil Pwny when selecting the custom list enhancement option
- Passwords with dates appended starting from the year 1950 up to 10 years from today's date (e.g. `password1950`, `password2034`)

A custom password list of 100 plaintext passwords generates 49848660 variations.

### Usernames in Passwords
Lil Pwny looks for users that are using variations of their username as their password.

It converts the users username into the following formats:

- All uppercase
- All lowercase
- Remove dot "."
- camelCase (E.g. johnSmith)
- PascalCase (E.g. JohnSmith)

These are then converted to NTLM hashes, and audited against the AD hashes

## Resources
This application has been developed to make the most of multiprocessing in Python, with the aim of it working as fast as possible on consumer level hardware.

Because it uses multiprocessing, the more cores you have available, the faster Lil Pwny should run. I have still had very good results with a low number of logical cores:
- Test env of ~8500 AD accounts and HIBP list of 613,584,246 hashes:
    - 6 logical cores - 0:05:57.640813
    - 12 logical cores - 0:04:28.579201

## Output
Lil Pwny will output results as either to stdout:

<img src="./images/stdout-screenshot.png" width="675">

or JSON:

```json
{"localtime": "2021-00-00 00:00:00,000", "level": "NOTIFY", "source": "Lil Pwny", "match_type": "hibp", "detection_data": {"username": "RICKON.STARK", "hash": "32ED87BDB5FDC5E9CBA88547376818D4", "matches_in_hibp": "24230577", "obfuscated": "True"}}
```
You can redirect the JSON output of Lil Pwny to file:
```commandline
lil-pwny -ad ... > lil-pwny-results.json 
```

This JSON formatted logging can be easily ingested in to a SIEM or other log analysis tool, and can be fed to other scripts or platforms for automated resolution actions.

## Installation
Install via pip
```bash
pip install lil-pwny
```

## Usage
Lil-pwny will be installed as a global command, use as follows:

```
usage: lil-pwny [-h] -hibp HIBP [-v] [-c CUSTOM] [-custom-enhance CUSTOM_ENHANCE] -ad AD_HASHES [-d] [-output {file,stdout,json}] [-o] [--verbose]

Fast offline auditing of Active Directory passwords using Python

options:
  -h, --help            show this help message and exit
  -hibp HIBP, --hibp HIBP
                        The .txt file containing HIBP NTLM hashes
  -v, --version         show program's version number and exit
  -c CUSTOM, --custom CUSTOM
                        .txt file containing additional custom passwords to check for
  -custom-enhance CUSTOM_ENHANCE, --custom-enhance CUSTOM_ENHANCE
                        generate an enhanced custom password list based on the provided custom password list. Must be used with -c/--custom flag. The enhanced list will stored in memory and not
                        written to disk. Provide the minimum length of the passwords you want. Default is 8
  -ad AD_HASHES, --ad-hashes AD_HASHES
                        The .txt file containing NTLM hashes from AD users
  -d, --duplicates      Output a list of duplicate password users
  -output {file,stdout,json}, --output {file,stdout,json}
                        Where to send results
  -o, --obfuscate       Obfuscate hashes from discovered matches by hashing with a random salt
  --verbose             Turn on verbose logging

```

Example:
```bash
lil-pwny -hibp ~/hibp_hashes.txt -ad ~/ad_user_hashes.txt -c ~/custom_passwords.txt -output stdout -do
```



## Getting input files
### Step 1: Get an IFM AD database dump

On a domain controller use `ntdsutil` to generate an IFM dump of your AD domain. Run the following in an elevated PowerShell window:

```bash
ntdsutil
activate instance ntds
ifm
create full **output path**
```

### Step 2: Recover NTLM hashes from this output

To recover the NTLM hashes from the AD IFM data, the Powershell module [DSInternals](https://github.com/MichaelGrafnetter/DSInternals) is required.

Once installed, use the SYSTEM hive in the IFM data to recover the hashes in the format `usernme:hash` and save them to the file `ad_ntlm_hashes.txt`

```bash
$bootKey = Get-BootKey -SystemHivePath '.\registry\SYSTEM'
Get-ADDBAccount -All -DBPath '.\Active Directory\ntds.dit' -BootKey $bootKey | Format-Custom -View HashcatNT | Out-File ad_ntlm_hashes.txt -Encoding ASCII
```

### Step 3: Download the latest HIBP hash file
The file can be downloaded from the HIBP API using a .net utility  [here](https://github.com/HaveIBeenPwned/PwnedPasswordsDownloader)

### Optional Step: Filter unwanted AD accounts
The PowerShell script in the [scripts](./scripts/Filter-ADUsers) directory can be used to remove unwanted accounts from the IFM output before processing. These include:

- Disabled accounts
- Computer accounts


## Resources
- [ntdsutil & IFM](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc732530(v=ws.11))

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "lil-pwny",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": null,
    "author": "PaperMtn",
    "author_email": "papermtn@protonmail.com",
    "download_url": "https://files.pythonhosted.org/packages/51/90/046ac816e04e463e487817f8cfd03126d98a393a2a10edb84efc97f315c2/lil_pwny-3.2.0.tar.gz",
    "platform": null,
    "description": "<img src=\"https://i.imgur.com/Q0pPSjN.png\" width=\"450\">\n\n# Lil Pwny\n![Python 2.7 and 3 compatible](https://img.shields.io/pypi/pyversions/lil-pwny)\n![PyPI version](https://img.shields.io/pypi/v/lil-pwny.svg)\n![License: MIT](https://img.shields.io/pypi/l/lil-pwny.svg)\n\nFast offline auditing of Active Directory passwords using Python.\n\n## About Lil Pwny\nLil Pwny is a Python application to perform an offline audit of NTLM hashes of users' passwords, recovered from Active Directory, against known compromised passwords from Have I Been Pwned. Results will be output in JSON format containing the username, matching hash (can be obfuscated), and how many times the matching password has been seen in HIBP\n\nMore information about Lil Pwny can be found [on my blog](https://papermtn.co.uk/category/tools/lil-pwny/)\n\n## Features\n\n- **Custom Password Auditing**: Ability to provide a list of your own custom passwords to check AD users against. This allows you to check user passwords against passwords relevant to your organisation that you suspect people might be using. \n  - Pass a .txt file with the plaintext passwords you want to search for, these are then NTLM hashed and AD hashes are then compared with this as well as the HIBP hashes.\n- **Detect Duplicates**: Return a list of accounts using the same passwords. Useful for finding users using the same password for their administrative and standard accounts.\n- **Username as Password**: Detect users that are using their username, or variations of it, as their password.\n- **Obfuscated Output**: Obfuscate hashes in output, for if you don't want to handle or store live user NTLM hashes.\n\n### Custom Password List Enhancement\nLil Pwny provides the functionality to enhance your custom password list by adding commonly used variants of your custom passwords. These include:\n- Passwords with common 'leetspeak' substitutions (e.g. `P@ssw0rd`)\n- Uppercase versions of the password, and uppercase first characters (e.g. `PASSWORD`, `Password`)\n- Passwords with common special characters appended or prepended (e.g. `password!`, `!password`)\n- Passwords padded with common alphanumeric characters, special characters and repetitions of themselves to make them meet a given minimum length (e.g. `password123!`, `!passwordabc`, `passwordpassword`)\n  - You pass your desired minimum password length to Lil Pwny when selecting the custom list enhancement option\n- Passwords with dates appended starting from the year 1950 up to 10 years from today's date (e.g. `password1950`, `password2034`)\n\nA custom password list of 100 plaintext passwords generates 49848660 variations.\n\n### Usernames in Passwords\nLil Pwny looks for users that are using variations of their username as their password.\n\nIt converts the users username into the following formats:\n\n- All uppercase\n- All lowercase\n- Remove dot \".\"\n- camelCase (E.g. johnSmith)\n- PascalCase (E.g. JohnSmith)\n\nThese are then converted to NTLM hashes, and audited against the AD hashes\n\n## Resources\nThis application has been developed to make the most of multiprocessing in Python, with the aim of it working as fast as possible on consumer level hardware.\n\nBecause it uses multiprocessing, the more cores you have available, the faster Lil Pwny should run. I have still had very good results with a low number of logical cores:\n- Test env of ~8500 AD accounts and HIBP list of 613,584,246 hashes:\n    - 6 logical cores - 0:05:57.640813\n    - 12 logical cores - 0:04:28.579201\n\n## Output\nLil Pwny will output results as either to stdout:\n\n<img src=\"./images/stdout-screenshot.png\" width=\"675\">\n\nor JSON:\n\n```json\n{\"localtime\": \"2021-00-00 00:00:00,000\", \"level\": \"NOTIFY\", \"source\": \"Lil Pwny\", \"match_type\": \"hibp\", \"detection_data\": {\"username\": \"RICKON.STARK\", \"hash\": \"32ED87BDB5FDC5E9CBA88547376818D4\", \"matches_in_hibp\": \"24230577\", \"obfuscated\": \"True\"}}\n```\nYou can redirect the JSON output of Lil Pwny to file:\n```commandline\nlil-pwny -ad ... > lil-pwny-results.json \n```\n\nThis JSON formatted logging can be easily ingested in to a SIEM or other log analysis tool, and can be fed to other scripts or platforms for automated resolution actions.\n\n## Installation\nInstall via pip\n```bash\npip install lil-pwny\n```\n\n## Usage\nLil-pwny will be installed as a global command, use as follows:\n\n```\nusage: lil-pwny [-h] -hibp HIBP [-v] [-c CUSTOM] [-custom-enhance CUSTOM_ENHANCE] -ad AD_HASHES [-d] [-output {file,stdout,json}] [-o] [--verbose]\n\nFast offline auditing of Active Directory passwords using Python\n\noptions:\n  -h, --help            show this help message and exit\n  -hibp HIBP, --hibp HIBP\n                        The .txt file containing HIBP NTLM hashes\n  -v, --version         show program's version number and exit\n  -c CUSTOM, --custom CUSTOM\n                        .txt file containing additional custom passwords to check for\n  -custom-enhance CUSTOM_ENHANCE, --custom-enhance CUSTOM_ENHANCE\n                        generate an enhanced custom password list based on the provided custom password list. Must be used with -c/--custom flag. The enhanced list will stored in memory and not\n                        written to disk. Provide the minimum length of the passwords you want. Default is 8\n  -ad AD_HASHES, --ad-hashes AD_HASHES\n                        The .txt file containing NTLM hashes from AD users\n  -d, --duplicates      Output a list of duplicate password users\n  -output {file,stdout,json}, --output {file,stdout,json}\n                        Where to send results\n  -o, --obfuscate       Obfuscate hashes from discovered matches by hashing with a random salt\n  --verbose             Turn on verbose logging\n\n```\n\nExample:\n```bash\nlil-pwny -hibp ~/hibp_hashes.txt -ad ~/ad_user_hashes.txt -c ~/custom_passwords.txt -output stdout -do\n```\n\n\n\n## Getting input files\n### Step 1: Get an IFM AD database dump\n\nOn a domain controller use `ntdsutil` to generate an IFM dump of your AD domain. Run the following in an elevated PowerShell window:\n\n```bash\nntdsutil\nactivate instance ntds\nifm\ncreate full **output path**\n```\n\n### Step 2: Recover NTLM hashes from this output\n\nTo recover the NTLM hashes from the AD IFM data, the Powershell module [DSInternals](https://github.com/MichaelGrafnetter/DSInternals) is required.\n\nOnce installed, use the SYSTEM hive in the IFM data to recover the hashes in the format `usernme:hash` and save them to the file `ad_ntlm_hashes.txt`\n\n```bash\n$bootKey = Get-BootKey -SystemHivePath '.\\registry\\SYSTEM'\nGet-ADDBAccount -All -DBPath '.\\Active Directory\\ntds.dit' -BootKey $bootKey | Format-Custom -View HashcatNT | Out-File ad_ntlm_hashes.txt -Encoding ASCII\n```\n\n### Step 3: Download the latest HIBP hash file\nThe file can be downloaded from the HIBP API using a .net utility  [here](https://github.com/HaveIBeenPwned/PwnedPasswordsDownloader)\n\n### Optional Step: Filter unwanted AD accounts\nThe PowerShell script in the [scripts](./scripts/Filter-ADUsers) directory can be used to remove unwanted accounts from the IFM output before processing. These include:\n\n- Disabled accounts\n- Computer accounts\n\n\n## Resources\n- [ntdsutil & IFM](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc732530(v=ws.11))\n",
    "bugtrack_url": null,
    "license": "GPL-3.0",
    "summary": "Fast offline auditing of Active Directory passwords using Python and multiprocessing",
    "version": "3.2.0",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "45c3a31fb8188fd26f67ae6133e0a4fd8d4ed929428355049773262d8db471f1",
                "md5": "23b3ee4b33a79e09447f52c42711d1ca",
                "sha256": "43e09187fe8fed23343d40b332a9eaf781437ab0540d3f1969b5de475ff8e082"
            },
            "downloads": -1,
            "filename": "lil_pwny-3.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "23b3ee4b33a79e09447f52c42711d1ca",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 31072,
            "upload_time": "2024-08-14T19:14:59",
            "upload_time_iso_8601": "2024-08-14T19:14:59.278521Z",
            "url": "https://files.pythonhosted.org/packages/45/c3/a31fb8188fd26f67ae6133e0a4fd8d4ed929428355049773262d8db471f1/lil_pwny-3.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5190046ac816e04e463e487817f8cfd03126d98a393a2a10edb84efc97f315c2",
                "md5": "bb077888f55ddb1329e7c113ec65db56",
                "sha256": "17449497a6013c6cfb5a71b3707c0d536490f8ace930f84d101a38d339609faa"
            },
            "downloads": -1,
            "filename": "lil_pwny-3.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "bb077888f55ddb1329e7c113ec65db56",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 30731,
            "upload_time": "2024-08-14T19:15:00",
            "upload_time_iso_8601": "2024-08-14T19:15:00.665803Z",
            "url": "https://files.pythonhosted.org/packages/51/90/046ac816e04e463e487817f8cfd03126d98a393a2a10edb84efc97f315c2/lil_pwny-3.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-14 19:15:00",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "lil-pwny"
}
        
Elapsed time: 0.68942s