Application of Password Filter DLL in Penetration Testing

Onedaysec
6 min read
1 views
docx image 1770018746891 0 2a27d1331e

0x00 Preface

---

In the previous article 'Domain Penetration – Hook PasswordChangeNotify', we introduced the method of recording new passwords by injecting a DLL to hook PasswordChangeNotify, which essentially exploits the API PasswordChangeNotify.

We know that API PasswordChangeNotify is a functional function of the Password Filter DLL. So, for the Password Filter DLL itself, can we directly develop a DLL that can be exploited?

0x01 Introduction

---

This article will cover the following:

  • Introduction to Password Filter DLL
  • Using Password Filter DLL to Record Plaintext Passwords
  • Backdoor Implementation Using Password Filter DLL
  • Application in Non-Windows Server Systems

0x02 Introduction to Password Filter DLL

---

In real-world use of Windows systems, to enhance security and prevent brute-force attacks on user passwords, system administrators often impose complexity requirements for user passwords, which can be enabled by configuring Group Policy.

The location is as follows:

gpedit.msc -> Local Computer Policy -> Computer Configuration -> Windows Settings -> Security Settings -> Account Policies -> Password Policy -> Password must meet complexity requirements

When enabled, passwords must meet the following minimum requirements:

  • Cannot contain the user's account name or more than two consecutive characters from the user's full name
  • At least six characters long
  • Contain characters from three of the following four categories:
  • Uppercase English letters (A through Z)
  • Lowercase English letters (a through z)
  • Base 10 digits (0 through 9)
  • Non-alphabetic characters (e.g., !, $, #, %)

Default:

  • Enabled on domain controllers
  • Disabled on standalone servers

If this policy still does not meet password complexity requirements, a Password Filter DLL can be used to further enhance password complexity

Implementation approach:

  1. Installing Password Filter DLL by modifying the registry
  2. Automatically loading Password Filter DLL and importing plaintext passwords when users change passwords
  3. Developers can define password complexity in the Password Filter DLL and compare it with the complexity of plaintext passwords; if the plaintext password does not meet the complexity requirements, a dialog box prompts the user and the password change fails

For specific usage, refer to the official documentation:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms721766(v=vs.85).aspx

0x03 Development of Password Filter DLL

---

Supports the following three functions:

  • BOOLEAN InitializeChangeNotify(void);
  • NTSTATUS PasswordChangeNotify(_In_ PUNICODE_STRING UserName,_In_ ULONG RelativeId,_In_ PUNICODE_STRING NewPassword);
  • BOOLEAN PasswordFilter(_In_ PUNICODE_STRING AccountName,_In_ PUNICODE_STRING FullName,_In_ PUNICODE_STRING Password,_In_ BOOLEAN SetOperation);

Reference materials:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms721849(v=vs.85).aspx#password_filter_functions

Notable points:

  • The input parameters for the APIs PasswordChangeNotify and PasswordFilter both include the user's plaintext password
  • When the API PasswordFilter returns TRUE, it indicates the password meets requirements; returning FALSE means the password does not meet complexity requirements, and a dialog prompts the user to modify it.
  • When writing a Password Filter DLL, it is necessary to declare export functions.

A proof-of-concept (POC) for reference is provided at the following address:

An open-source project

This project declares the export functions InitializeChangeNotify, PasswordChangeNotify, and PasswordFilter.

Use PasswordChangeNotify and PasswordFilter respectively to record plaintext passwords, saved in c:\logFile1 and c:\logFile2.

During compilation, it must correspond to the target system's platform.

%wZ indicates outputting PUNICODE_STRING, a Unicode string pointer type.

0x04 Installation of Password Filter DLL

---

1. In the registry at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa, under Notification Packages, add the name of the Password Filter DLL, excluding the .dll suffix.

2. Save the Password Filter DLL in %windir%\system32\.

3. Enable the group policy 'Password must meet complexity requirements'.

4. Restart the system (logging off the current user will not take effect).

5. Modify any user's password to load the Password Filter DLL.

Actual test:

Test system: Windows Server 2008 R2 x64

Compile the Password Filter DLL project to generate the 64-bit Win32Project3.dll

1. Save Win32Project3.dll under %windir%\system32\

2. Modify the Notification Packages registry key under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa, add Win32Project3

As shown in the figure below

Actual test: — technical illustration 1

The method to achieve via command line is as follows:

Read the key value:

REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "Notification Packages"

Obtain the key value content:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
Notification Packages REG_MULTI_SZ scecli\0rassfm

Add Win32Project3:

REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "Notification Packages" /t REG_MULTI_SZ /d "scecli\0rassfm\0Win32Project3" /f

Note:

\0 indicates a line break

3. The group policy of Windows Server systems by default enforces that passwords must meet complexity requirements

4. Restart the system

5. Change user password

6. Record plaintext password

As shown in the figure below

Actual test: — technical illustration 2

Note:

Can record all users, including those not logged in

0x05 Applications in Domain Environment

---

1. Record plaintext password

For domain controller servers, domain controller server permissions are required. Place the Password Filter DLL under %windir%\system32\ and modify the registry key value

Advantages:

Domain controller servers have the group policy 'Password must meet complexity requirements' enabled by default

Drawback:

Requires a system reboot to take effect, which is rare for domain controllers

Extension:

Modify the payload to send plaintext passwords to a web server; refer to the code at:

https://malicious.link/post/2013/2013-09-11-stealing-passwords-every-time-they-change/

2. Backdoor

Change the Password Filter DLL to launch a backdoor, such as returning a Meterpreter shell

When any domain user changes their password, the Password Filter DLL loads and returns a high-privilege shell

0x06 Application on Non-Windows Server Systems

---

Most current information suggests Password Filter DLLs are only applicable to Windows Server systems

For non-Windows Server systems, they can also be used, but the group policy 'Password must meet complexity requirements' is disabled by default

Therefore, note the following issues:

1. Check the current system's group policy configuration via command line

Group Policy configuration is stored in a database located at %windir%\security\database\secedit.sdb

The read command is as follows (administrator privileges):

secedit /export /cfg gp.inf /quiet

Parameter description:

  • The /db parameter is not set, indicating the database uses the default %windir%\security\database\secedit.sdb
  • /quiet means no log is generated; otherwise, the generated log is saved by default at %windir%\security\logs\scesrv.log

After command execution, the file gp.inf is generated. Check the PasswordComplexity item in gp.inf; 1 indicates enabled, 0 indicates disabled

Note:

The content in gp.inf is incomplete; to obtain the complete Group Policy configuration, the registry must also be read

2. Modify Group Policy configuration to enable the policy that passwords must meet complexity requirements

First, export the configuration file gp.inf, set the PasswordComplexity item to 1, and save

Import into the database:

secedit /configure /db gp.sdb /cfg gp.inf /quiet

Refresh Group Policy to take effect immediately (otherwise, it takes effect after restart):

gpupdate /force

0x07 Defense Detection

---

According to the exploitation methodology, the attacker first needs to obtain administrator privileges on the current system.

The detection approach is as follows:

1. Check for suspicious DLLs under %windir%\system32\

2. Check the Notification Packages registry key value under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

3. Check the DLLs loaded by the lsass.exe process

As shown in the figure below

0x07 Defense Detection — technical illustration 3

0x08 Summary

---

Password Filter DLL is a legitimate function provided by the system. However, if system administrator privileges are obtained, this functionality can be exploited not only to record plaintext passwords but also to serve as a backdoor.

This article, in conjunction with specific exploitation methodologies, introduces detection methods.

Related Questions & Answers

How can defenders detect and prevent the misuse of Password Filter DLLs?

Defenders should monitor `%windir%\system32\` for suspicious DLLs (especially recently added ones), check the `Notification Packages` registry key for unknown entries, and enable [Additional LSA Protection](/news/configure-additional-lsa-protection-to-monitor-password-filter-dll) to prevent unauthorized LSA plug-ins. Regularly auditing password change events and using file integrity monitoring can also help. Attackers must already have admin privileges, so enforcing least privilege is critical.

How can a Password Filter DLL be applied on non-Windows Server systems that have password complexity disabled?

On non-server systems, password complexity is disabled by default. To use a Password Filter DLL, an attacker must first enable the policy by exporting the current security database with `secedit /export /cfg gp.inf`, set `PasswordComplexity=1`, then import it with `secedit /configure` and refresh Group Policy with `gpupdate /force`. After that, the standard installation steps (registry, DLL placement, reboot) apply, allowing password capture on workstations.

How can a Password Filter DLL be used in a domain environment for backdoor or credential theft?

On a domain controller, an attacker with administrative privileges can deploy a malicious Password Filter DLL to capture plaintext passwords from all domain users when they change passwords, or use it as a backdoor to return a reverse shell (e.g., Meterpreter). Since domain controllers have the password complexity policy enabled by default, only reboot is needed for activation. This technique complements other credential theft methods like [retrieving passwords from Windows Credential Manager](/news/penetration-techniques-information-retrieval-from-windows-credential-manager).

What are the steps to install a malicious Password Filter DLL on a Windows system?

First, compile the malicious DLL for the target platform and copy it to `%windir%\system32\`. Then, add the DLL name (without extension) to the registry key `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Notification Packages`. Ensure the group policy 'Password must meet complexity requirements' is enabled, and then restart the system for the DLL to load. After reboot, any user password change triggers the DLL, allowing password capture.

What is a Password Filter DLL and how can an attacker exploit it in penetration testing?

A Password Filter DLL is a Windows component that enforces custom password complexity policies by processing plaintext passwords during password changes. Attackers can exploit it by developing a malicious DLL that implements the `PasswordChangeNotify` function to record plaintext passwords or even drop a backdoor, as described in [Application of Password Filter DLL in Penetration Testing](/news/application-of-password-filter-dll-in-penetration-testing). This technique is similar to hooking `PasswordChangeNotify` but leverages the native DLL interface.

Continue Reading