← Back to blog

Evill-SSP: Understanding Security Support Providers as an Attack Vector

Introduction

Evill-SSP is a research project I built to explore an often-underestimated attack technique: hijacking Windows Security Support Providers (SSP) to intercept system credentials. SSPs run inside LSASS with SYSTEM privileges and receive credentials in plaintext at every authentication. That makes them a prime post-exploitation target.

This project is strictly for educational purposes. The full implementation is not detailed here, and using these techniques on any system without authorization is illegal.

Security Support Providers

SSPs are DLLs that implement the Security Support Provider Interface (SSPI), allowing Windows applications to authenticate in a standardized way. They run inside the LSASS (Local Security Authority Subsystem Service) process, each handling a specific authentication protocol.

Windows ships with: Kerberos for AD environments, NTLM for challenge-response authentication, Negotiate which picks between the two automatically, Schannel for SSL/TLS, and CredSSP for credential delegation.

SSPs are registered under two registry keys beneath HKLM\SYSTEM\CurrentControlSet\Control\Lsa. LSASS loads them at boot, or dynamically via the AddSecurityPackage API without a reboot. That’s the attack surface: modify the registry key, drop a DLL in System32, and LSASS loads it on the next boot.

SSPs as an Attack Vector

Background

The technique was popularized by Mimikatz and its mimilib component, developed by Benjamin Delpy starting in 2011 (mimikatz). The idea: an SSP receives credentials in plaintext via SSPI, so a malicious SSP DLL can intercept them before any encryption happens. This isn’t a bug, it’s the protocol working as intended. The SSP has to receive plaintext credentials to do its job.

A DLL loaded into LSASS gets access to plaintext passwords, NTLM hashes, and Kerberos tickets for every user who authenticates on the machine. With SYSTEM-level execution and automatic loading at every boot.

In the MITRE ATT&CK framework, this is T1547.005 - Boot or Logon Autostart Execution: Security Support Provider, under the Persistence tactic.

What Needs to Be Implemented

For a DLL to be accepted by LSASS as a valid SSP, it must expose several SSPI interface functions. Three matter most.

SpLsaModeInitialize() is called when the SSP loads into LSASS, this is where it registers itself and declares its capabilities.

SpAcceptCredentials() is the core of the whole thing. LSASS calls it on every successful authentication, passing the auth type, username, domain, and credentials, plaintext password or hash depending on the protocol. This is where the interception happens.

SpShutdown() is called when LSASS shuts down, useful for flushing any remaining collected data.

Exfiltration

Evill-SSP exfiltrates credentials over HTTP or HTTPS to a remote server. The operational advantage: outbound HTTP/HTTPS is rarely blocked on enterprise networks. HTTPS also makes traffic inspection harder without an SSL broker.

Real Constraints

The main prerequisite is admin or SYSTEM rights to modify LSA registry keys and write to System32 which limits this to post-exploitation. On a hardened system, the obstacles stack up: Driver Signature Enforcement, ELAM, LSA Protection (RunAsPPL), and Credential Guard can all block deployment. That’s where it gets interesting.

Detection and Defense

Detecting

Registry: any modification to HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages or OSConfig\Security Packages should trigger an alert. The list of legitimate SSPs is stable, any new entry is abnormal.

Process: monitor DLLs loaded into LSASS, particularly unsigned ones or those from unexpected paths. The EnumerateSecurityPackages API lists registered providers, allowing comparison against a known-good baseline.

Network: LSASS doesn’t normally initiate outbound connections. HTTP/HTTPS traffic originating from lsass.exe is a strong IOC.

Correlation: registry modification + DLL write to System32 + unusual network connection that trifecta is the pattern to watch for, ideally before the first credential is intercepted.

IOC

  • Security Packages key recently modified, unknown DLLs in the package list
  • DLLs in System32 without valid signatures or with inconsistent timestamps
  • HTTP/HTTPS connections from lsass.exe to external IPs

LSA Protection

Enabling RunAsPPL configures LSASS as a Protected Process Light, blocking unsigned Microsoft DLLs from loading. Bypassing it typically requires a vulnerable signed driver which significantly raises the cost of the attack.

Credential Guard

Credential Guard isolates authentication secrets into a separate process (LsaIso.exe) using VBS (Virtualization-Based Security). NTLM hashes, Kerberos TGTs, and domain credentials are stored in that isolated environment, inaccessible to the rest of the system including any malicious SSPs.

Its limits: Credential Guard doesn’t run on domain controllers, and doesn’t protect credentials entered interactively for NTLM authentication in that case they pass through LSASS memory before isolation. As of Windows Server 2025, it’s enabled by default on machines meeting the hardware requirements.

Additional Hardening

AppLocker or WDAC can restrict which DLLs are allowed to run. MFA and zero-trust network segmentation limit the blast radius if credentials do get collected.

Conclusion

This project gave me a much clearer picture of Windows authentication internals and the friction an attacker actually faces on a modern hardened system. The SSP technique is powerful but requires elevated privileges and becomes increasingly hard to deploy as RunAsPPL and Credential Guard become standard. LSASS deserves dedicated monitoring and maximum protection, RunAsPPL + Credential Guard + EDR + registry monitoring is the only approach that holds up.

Resources