Skip to content

Unsigned or Oddly Signed Modules

Red Flags

A process loads DLLs, modules of code that run inside it, and every program loads some of Windows' own, which Microsoft signs, many through a catalogue rather than inside the file. SigmaHQ flags an unsigned module loaded into lsass.exe, the Local Security Authority, which holds credentials, and lsass.exe under added LSA protection refuses any plug-in without a Microsoft signature. An unsigned or oddly signed DLL in a trusted process usually means code running with everything its host holds, which in lsass.exe is the credentials. List the modules with their paths and signers first, using a check that reads catalogue signatures.

Normal and Suspicious

A clean machine sits beside a suspicious one, and the pointer marks where to look.

Normal

A clean Windows 11 install

A Windows DLL lsass.exe loads at start on a clean install, from System32. Example values.
NamePathSigned By
kernel32.dllC:\Windows\System32\kernel32.dllMicrosoft Windows
See It in the Window

Suspicious

srv-fin-01,

An illustration of lsass.exe on srv-fin-01 at 06:15 on 7 Oct 2026, with a DLL no clean install of the build has.
NamePathSigned By
lsaext.dllC:\Windows\System32\lsaext.dllNot signed
Signed ByNot signed, inside lsass.exe: Windows' own modules there are signed by Microsoft. Unsigned or Oddly Signed Modules

Look Inside

Why It Matters

A DLL runs with everything its host process holds, so an unsigned module inside lsass.exe can read credentials. Windows' own modules are signed by Microsoft, many through a catalogue, a signed file that lists their hashes, rather than inside the file.

How to Confirm It

Work through these in order. Each step names the page that shows how.

  1. List the modules with their paths and signers (ListDLLs, Process Explorer's DLL view, Windows.System.DLLs), using a check that reads catalogue signatures.Loaded DLLs
  2. For lsass.exe, read CodeIntegrity events 3065 and 3066 (audit mode, on by default from Windows 11 version 22H2) and 3033 and 3063 (enforced) in the Microsoft-Windows-CodeIntegrity/Operational log. They name plug-ins that fail its signing or shared-section rules.Loaded DLLs
  3. In a memory image, set the loader's three lists against every region that starts with an MZ header, using windows.malware.ldrmodules. A region in no list is a lead, not a verdict, since the process's own executable is missing from the initialisation list and resource files from all three.Loaded DLLs
  4. Extract the DLL with windows.dlllist and its dump option, or take the file on disk, and check its signature and hash offline. Volatility lists modules but does not check signatures.Dumping a Process and Memory

What Defenders See

Each record names its log and what must be switched on to get it.

Record and Where It LandsWhat to ReadHow to Turn It On
7 Image loaded (opens in a new tab)Microsoft-Windows-Sysmon/OperationalIt is written on any Windows computer running Sysmon.Image, ImageLoaded, Signed, Signature and SignatureStatus for each load. It is off by default and needs a filtered configuration.Loaded DLLs shows how to read it.Run Sysmon with ImageLoad events in its configuration. They are off by default.
DeviceImageLoadEvents (opens in a new tab)Each row is a DLL load, showing which module loaded into which process. The table has no signature columns, so join it to DeviceFileCertificateInfo on SHA1 to see who signed the module.Defender XDR, advanced huntingWhich module loaded into which process. It has no signature columns, so join DeviceFileCertificateInfo on SHA1.The Defender for Endpoint sensor on the device
DeviceFileCertificateInfo (opens in a new tab)Each row is the signing certificate of a file seen on devices. It says whether the signature is embedded or comes from a catalogue file, and whether it is trusted.Defender XDR, advanced huntingIsSigned, IsTrusted, Signer and IsRootSignerMicrosoft for the module, by its SHA1.The Defender for Endpoint sensor on the device
3066 A code integrity check determines that a process, usually LSASS.exe, attempts to load a driver that doesn't meet the Microsoft signing level requirements. However, due to the system policy currently set, the image is allowed to load (opens in a new tab)Microsoft-Windows-CodeIntegrity/OperationalIt is written on any computer that audits LSA protection. That audit is on by default from Windows 11 version 22H2.In audit mode, lsass.exe loaded a plug-in or driver that does not meet Microsoft's signing level, and enforcement would refuse it.Loaded DLLs shows how to read it.Turn on audit mode for added LSA protection, which allows the load and logs it.
3065 A code integrity check determines that a process, usually LSASS.exe, attempts to load a driver that doesn't meet the security requirements for shared sections. However, due to the system policy currently set, the image is allowed to load (opens in a new tab)Microsoft-Windows-CodeIntegrity/OperationalIt is written on any computer that audits LSA protection. That audit is on by default from Windows 11 version 22H2.In audit mode, a plug-in or driver with shared sections, which Microsoft says is logged together with 3066.Loaded DLLs shows how to read it.Turn on audit mode for added LSA protection, which allows the load and logs it.
3033 A code integrity check determines that a process, usually LSASS.exe, attempts to load a driver that doesn't meet the Microsoft signing level requirements (opens in a new tab)Microsoft-Windows-CodeIntegrity/OperationalIt is written on any computer that runs lsass.exe as a protected process.Under enforcement, a protected lsass.exe refused a plug-in or driver that does not meet Microsoft's signing level.Loaded DLLs shows how to read it.Turn on added LSA protection, which then refuses the plug-in or driver.
3063 A code integrity check determines that a process, usually LSASS.exe, attempts to load a driver that doesn't meet the security requirements for shared sections (opens in a new tab)Microsoft-Windows-CodeIntegrity/OperationalIt is written on any computer that runs lsass.exe as a protected process.Under enforcement, a protected lsass.exe refused a plug-in or driver that breaks the shared sections rules.Loaded DLLs shows how to read it.Turn on added LSA protection, which then refuses the plug-in or driver.

What It Looks Like

This record is decoded field by field, with what each value means.

7 Image loaded (opens in a new tab)On srv-fin-01, . An illustration of Sysmon event 7 on srv-fin-01 on 7 Oct 2026.
Field, as the Record Writes ItWhat It Tells You
ImageC:\Windows\System32\lsass.exeThe process that loaded the module, the Local Security Authority. Whatever it loads can read the credentials it holds.
ImageLoadedC:\Windows\System32\lsaext.dllThe DLL, in System32, where LSA plug-ins live. The folder looks right, so the signature has to decide.
SignedfalseNo signature vouches for it. A protected lsass.exe would have refused it and logged CodeIntegrity event 3033.
False Positives

Windows DLLs signed through a catalogue look unsigned to a check that reads only embedded signatures.

Smart card drivers, cryptographic plug-ins and password filters load their own signed modules into lsass.exe, so check the signer is that vendor and that you run the product.

Blind Spots

A protected lsass.exe refuses tools that are not protected, so a live module list for it can come back empty. Rely on CodeIntegrity events and image load records.

Sysmon logs image loads only when its configuration asks, and a DLL loaded before the sensor started has no record.

Hunt It

The same hunt is written for four tools, so pick the one you use. Defender XDR and Sentinel queries are in KQL, which you paste into Advanced hunting in the Defender portal or into Sentinel's Logs page. Splunk queries are in SPL, for its Search page, and Velociraptor queries are in VQL, which you run as a hunt.

Needs Defender for Endpoint. Smart card and other LSA plug-in vendors sign their own modules, so a non-Microsoft signer is a lead to check, not a finding. A module with no certificate record may only be unchecked.

KQLDefender XDR, Advanced hunting
// Modules in lsass.exe and other core processes that are unsigned, untrusted, not Microsoft's or have no certificate record, rarest firstlet certs = DeviceFileCertificateInfo    | where Timestamp > ago(30d)    | summarize arg_max(Timestamp, IsSigned, IsTrusted, Signer, IsRootSignerMicrosoft) by SHA1    | project SHA1, IsSigned, IsTrusted, Signer, IsRootSignerMicrosoft;DeviceImageLoadEvents| where Timestamp > ago(30d)| where InitiatingProcessFileName in~ ("lsass.exe", "winlogon.exe", "services.exe", "spoolsv.exe") and isnotempty(SHA1)| join kind=leftouter certs on SHA1| where isnull(IsSigned) or not(IsSigned) or not(IsTrusted) or not(IsRootSignerMicrosoft)| summarize Loads = count(), Devices = dcount(DeviceName), FirstSeen = min(Timestamp)    by FileName, FolderPath, SHA1, Signer, IsSigned, IsTrusted, InitiatingProcessFileName| order by Devices asc, FirstSeen desc

In a Memory Image

Volatility 3 reads a memory image, and each of its plugins below shows part of this sign.

Rules to Compare With

Security vendors publish detection rules anyone can read. These look for the same thing, so compare your own with them.

Show the 5 Public Rules

How to Prevent It

Each control helps prevent it, and its line says what it does here.

Sources

MITRE ATT&CK is a free public catalogue of the techniques attackers use. Each technique has an ID, such as T1055 for Process Injection, so defenders can name the same behaviour the same way. This red flag can point to these techniques.