# Lithnet Password Protection for AD
A cool [password filter](https://docs.lithnet.io/password-protection) to stop people from picking weak passwords in AD!

## Install it
* [Download from GitHub](https://github.com/lithnet/ad-password-protection) and run the install wizard (I checked all the options).
* Reboot

## Prepare a password repository
The [documentation](https://docs.lithnet.io/password-protection) covers a way to do this via something like DFS, but for a single DC implementation:

```
# Make a folder to store passwords in
mkdir c:\passprotect

# Load the lithnet password protection module
import-module lithnetpasswordprotection

# Specify the "storepath" for passwords:
Set-PasswordFilterConfig -StorePath "c:\passprotect"

# Download all passwords from HaveIBeenPwned!
Sync-HashesFromHibp 
```

*Note - if you have problems with the HIBP hash download, try adding `-Threads 1` to the end of the command (per [this issue](https://github.com/lithnet/ad-password-protection/issues/147))*

## Adjust the lithnet GPO
Head to `Computer Configuration > Policies > Administrative Templates > Lithnet > Password Protection for Active Directory > Default Policy`, and set the properties you desire.  I went with:

* Enable *Reject passwords that contain the user's account name*
* Enable *Reject passwords that contain the user's display name*
* Enable *Reject passwords found in the compromised password store*
* Enable *Reject normalized passwords found in the compromised password store*
* Enable *Reject normalized passwords found in the banned word store*

:::warning
Be careful with this policy and make sure none of the settings conflict with `Computer Configuration > Policies > Windows Settings > Security Settings > Account Policies > Password Policy`.  I set *this* policy to establish:

* Password history
* Password maximum age
* Password minimum age
* Password length
* Enable password complexity
:::

### Review policy configuration
```
Get-PasswordFilterPolicy | fl
```

## Import a custom word list
In addition to the HIBP database, you can import custom word lists you've downloaded from places like [weakpass.com](https://weakpass.com)

```
Import-CompromisedPasswords -Filename "D:\password-protection\hashes.org-2018.txt"
```

## Add a specific password you don't want people to be able to pick
```
Add-CompromisedPassword -Value Meowmix2025!
```

### Test if a given password is blocked
```
Test-IsCompromisedPassword -Value Meowmix2025!
```

## Add *banned* passwords to the store
By adding passwords into the "banned" list, you essentially normalize those passwords and prevent common variations.  So for example, if you banned *lithnet* as a password, you'd also be banning *lithnet2018, l1thn3t,* and *Lithnet!* from being used.
```
# Import a list of banned words
Import-BannedWords -Filename "D:\password-protection\english-dictionary-words.txt"

# Import an individual banned word
Add-BannedWord -Value "7minutesecurity"
```

### Test if *banned* password is on the list
```
Test-IsBannedWord "7minutesecurity!"
Test-IsBannedWord "7minutesecurity2025"
Test-IsBannedWord "7m1nut3s3cur1ty2030!"
```

## Check filter actions in the event logs
Look in `Windows Logs > Application` for events such as *8195* which will show a user's password change was blocked due to not meeting the domain requirements and/or the lithnet filter's requirements.

## Video demo
<div style="padding:75% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/1140874763?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerpolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="tt-029-lithnet-ad-pw-FINAL"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
