Back to Articles

OpenPasswordFilter: Building a Custom Active Directory Password Filter Without Rebooting Your Domain Controllers

[ View on GitHub ]

OpenPasswordFilter: Building a Custom Active Directory Password Filter Without Rebooting Your Domain Controllers

Hook

The most common password in enterprise Active Directory environments isn't 'password123'—it's variations of the company name followed by the current season and year. OpenPasswordFilter exists because Microsoft's built-in password complexity rules won't catch 'Acme@Spring2024'.

Context

Active Directory's native password policies are embarrassingly inadequate for modern threat landscapes. The built-in complexity requirements check for character classes (uppercase, lowercase, numbers, symbols) but completely ignore dictionary words and contextual patterns. During penetration tests, security professionals routinely crack domain accounts using company-name-plus-season patterns, common sports teams, or leaked passwords from public breaches. Users will always choose 'Password1!' over random strings when given the chance—it satisfies Microsoft's complexity rules while remaining trivially guessable.

Commercial password filters exist to solve this problem, but they typically cost thousands of dollars annually and require vendor engagement processes. For small security teams, internal IT departments, or organizations in testing phases, this pricing model is prohibitive. OpenPasswordFilter emerged from this gap: a need for dictionary-based filtering without enterprise software budgets. It's the tool you reach for when you've just completed a pen test, cracked half your user accounts with rockyou.txt, and need to demonstrate security improvement before the next audit.

Technical Insight

Userspace Service

Password Change Request

Load at Boot

TCP localhost:5999

Check Exact Match

Check Substring

Approve/Reject

Validation Result

Allow/Deny

Update & Restart

Domain User

Windows LSASS

OpenPasswordFilter.dll

OPFService.exe

opfmatch.txt

opfcont.txt

Administrator

System architecture — auto-generated

The architectural challenge of Active Directory password filtering is that custom filters must be implemented as DLLs loaded by LSASS (Local Security Authority Subsystem Service) at boot time. Once loaded, these DLLs remain locked in memory—you can't update them without rebooting the domain controller. For production environments, this creates an impossible maintenance situation: you discover a new password pattern to block, but updating your filter requires scheduling DC downtime.

OpenPasswordFilter's solution is elegant: split the problem into two components. The DLL (OpenPasswordFilter.dll) registers with LSASS and implements the password filter interface, but contains minimal logic. It simply forwards password validation requests to OPFService.exe, a C# Windows service running in userspace. The service maintains the actual dictionary files and performs pattern matching. When you need to update your banned password lists, you modify text files and restart the service—a seconds-long operation that doesn't touch LSASS.

The communication happens over a localhost TCP connection. When a user attempts to change their password, LSASS calls into the DLL's PasswordFilter function. The DLL connects to the service (default port 5999), transmits the proposed password, and receives a boolean response: approved or rejected. Here's the core validation flow from the service side:

private bool checkPassword(string password) {
    // Convert to lowercase for case-insensitive matching
    string lowerPass = password.ToLower();
    
    // Check exact matches against opfmatch.txt
    if (exactMatches.Contains(lowerPass)) {
        return false;
    }
    
    // Check substring matches against opfcont.txt
    foreach (string substring in substringMatches) {
        if (lowerPass.Contains(substring)) {
            return false;
        }
    }
    
    return true;
}

The dual-dictionary approach is more sophisticated than it first appears. The exact match file (opfmatch.txt) contains full passwords to block—think entire entries from breach databases like rockyou.txt. The substring file (opfcont.txt) contains fragments that shouldn't appear anywhere in a password: company names, common words, sequential patterns. This catches leetspeak variations automatically. If 'password' is in your substring list, you'll block 'p@ssw0rd', 'MyPassword123', and 'password_admin' without maintaining an explosion of permutations.

The repository includes dictionary generation scripts that process the 14-million-entry rockyou.txt wordlist through hashcat rules, producing curated lists of common patterns. You can start with these defaults or build custom dictionaries matching your organization's context—local sports teams, product names, office locations.

Deployment requires installing both components on every domain controller. This is non-negotiable: AD distributes password change operations across DCs via RPC, so any controller might service a given request. The DLL must be placed in System32, registered via Windows registry entries, and the service installed as a Windows service. The installer packages handle most of this, but you're still manually touching each DC.

One implementation detail worth noting: the service loads dictionaries into memory at startup using HashSet collections for O(1) lookup performance. Even with millions of entries, password validation happens in milliseconds. The tradeoff is memory consumption—a 10-million-entry dictionary consumes several hundred megabytes of RAM—but modern domain controllers have resources to spare.

Gotcha

The project readme candidly labels itself 'very ALPHA' and warns of limited testing. Take this seriously. Custom password filters interact with LSASS, one of the most security-critical Windows processes. If your filter DLL crashes or deadlocks, you could prevent all domain password changes or, worse, destabilize domain controllers. The author tested on their own DCs, but your environment's specific Windows Server versions, patch levels, and configurations may expose unexpected behavior. Thoroughly test in lab environments that mirror production before deploying.

The localhost TCP communication model, while clever for enabling updates, introduces failure modes that in-process solutions avoid. If the service crashes or stops responding, what happens to password changes? The current implementation will reject passwords if it can't reach the service—a safe default that prevents bypassing validation, but also means service failures block legitimate password changes. You need monitoring to detect when OPFService.exe stops responding and alerting to restore it quickly. There's also a theoretical attack surface: while the service only listens on localhost, any process running on the DC could potentially connect and attempt to manipulate validation results. The security boundary isn't as tight as an in-process filter. Additionally, the per-DC installation requirement becomes genuinely painful in large environments with dozens of domain controllers, and there's no centralized management console—you're updating dictionaries on each server individually or scripting your own deployment automation.

Verdict

Use if: You're a small-to-medium organization (under 10 DCs) that needs dictionary-based password blocking without commercial software budgets, you've identified common passwords as a real security gap through testing or audits, and you have the technical capability to test alpha software thoroughly in lab environments before production deployment. It's particularly valuable if you need custom dictionaries matching your specific organizational context—company names, local references, industry terms—that generic commercial filters wouldn't include. Skip if: You require enterprise support contracts and guaranteed uptime, manage a large AD environment where per-DC manual installation creates unacceptable operational overhead, or lack the capacity to test and potentially troubleshoot alpha-quality software interacting with LSASS. Also skip if your organization already uses Azure AD Password Protection (which provides similar functionality with Microsoft support) or if you need compliance certifications that alpha open-source software can't provide. Consider commercial alternatives like Specops Password Policy if vendor support and extensive testing matter more than cost.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/jephthai-openpasswordfilter.svg)](https://starlog.is/api/badge-click/developer-tools/jephthai-openpasswordfilter)