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

Alt text

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

Alt text

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

Alt text

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.