False-Positive Hall of Fame No. 1: six alerts that were the software working

Chrome opens a pipe that Cobalt Strike also opens. Chrome's updater reads LSASS. Discord ships a signed binary that launches other binaries. Six alerts that fire on normal software, each with the benign explanation and the discriminator, and a count of how often the public rulebase admits any of this.

Every entry here is normal software doing its job and producing telemetry that matches a published detection rule. None of them is a bad rule. A rule that matches an attack technique will match anything else that uses the same technique, and quite a lot of ordinary Windows software uses the same technique because there is only one way to do the thing.

What separates a workable rule from an alert-fatigue generator is not the detection logic. It is whether anybody wrote down what else it hits.

Six entries. For each: what fires, what it actually is, and the discriminator that separates it from the genuine article.

1. Chrome opens a named pipe that Cobalt Strike also opens

What fires. A named-pipe creation rule for Cobalt Strike. Sysmon Event ID 17 and 18, matching pipe-name patterns taken from public malleable C2 profiles.

What it actually is. Chrome. Its Mojo inter-process communication layer creates pipes named mojo.<pid>.<tid>.<number>, and two of those exact names ended up hardcoded in malleable profiles, which is how they ended up in the rule. The SigmaHQ rule for this pattern lists the collision in its own false-positive block.

The discriminator. Two things, and you want both. First, the process holding the pipe: a mojo. pipe belongs to chrome.exe or another Chromium build, and a beacon impersonating one does not have Chrome's process ancestry or its module list. Second, the pipe name is generated from a real process ID and thread ID, so it changes every launch; a name that is stable across reboots is not Chrome's.

The wider point in that rule. Look at what it has to filter out to be usable: \wkssvc, \spoolss, \scerpc, \ntsvcs, \MsFteWds. Those are genuine Windows RPC endpoint names. They are in the rule because Cobalt Strike operators pick them deliberately, precisely so that this detection has to choose between missing them and drowning. That is not a flaw in the rule. It is the operator's design goal, working.

Documented at: SigmaHQ: CobaltStrike Named Pipe Patterns · ATT&CK T1055

2. Google's updater reads LSASS

What fires. Attack Surface Reduction event 1121, "block credential stealing from lsass.exe", or any Sysmon Event ID 10 rule watching for handles opened against lsass.exe. This is the marquee credential-theft detection on Windows.

What it actually is. GoogleUpdate.exe. The Sigma rule that reads the Defender ASR log names it as a known false positive, alongside some Task Manager activity.

The discriminator. Not the fact of the access. What matters is the granted access mask and what happens next. A dump needs read access to process memory; housekeeping does not. Pair the access event with a file-write of a .dmp, or with the calling module, before anybody is woken up. An access with no subsequent read of the memory and no artefact on disk is a different event from one followed by a 40 MB file appearing in %TEMP%.

Documented at: SigmaHQ: LSASS Access Detected via Attack Surface Reduction · Microsoft: Attack surface reduction rules · ATT&CK T1003.001

3. Discord ships a signed binary whose job is to launch other binaries

What fires. A signed executable in %LOCALAPPDATA% starting an arbitrary process, which is the shape of proxy execution through a trusted binary.

What it actually is. Squirrel, the update framework used by a long list of Electron applications. Update.exe --processStart <something>.exe is its documented interface. Hexacorn wrote this up in 2018 and again in 2019, under a title that has aged extremely well: many Electron apps are LOLBins by default. The SigmaHQ rule that covers it carries explicit path filters for Discord, GitHub Desktop and Teams, and a false-positive list naming another dozen applications.

The discriminator. The argument, not the binary. Squirrel launching the application that owns its own directory is the update mechanism working; \AppData\Local\Discord\Update.exe --processStart pointing at anything that is not Discord.exe is somebody using the updater as a launcher. Baseline the pairs you actually have and alert on the mismatch.

Documented at: SigmaHQ: Squirrel Lolbin · Hexacorn: Squirrel as a LOLBin · Hexacorn: many Electron apps are LOLBins by default · ATT&CK T1218

4. The management agent deletes your shadow copies, in encoded PowerShell

What fires. Shadow copy deletion. This is close to the highest-confidence signal in the ransomware playbook, because it has no purpose other than preventing recovery, and most teams page on it.

What it actually is. Sometimes an endpoint management agent. The SigmaHQ rule names LANDesk's client, running through an Ivanti PowerShell module, using an encoded command. Every aggravating factor at once: destruction of recovery data, invoked by PowerShell, with the command line obfuscated.

The discriminator. The parent process and the schedule. A management agent does this from a known service path, on a cadence, across a fleet, in a window somebody chose. An operator does it once, on the hosts they have reached, in an order that follows their lateral movement, minutes before the encryption. If you can only implement one thing here, implement the fleet-wide baseline: this alert is only usable if you know which hosts do it every week.

Documented at: SigmaHQ: Shadow Copies Deletion Using Operating Systems Utilities · Microsoft: vssadmin · ATT&CK T1490

5. wmic os get lastbootuptime loads a scripting engine

What fires. WMIC loading vbscript.dll or jscript.dll, which is the image-load signature for SquiblyTwo, proxy execution of a remote XSL through wmic /FORMAT.

What it actually is. Three of the most boring WMIC commands in existence. The rule's own false-positive block lists wmic os get lastbootuptime, wmic os get locale and wmic ntevent. WMIC formats its output through XSL, so it loads the scripting engine for queries that have nothing to do with anything.

The discriminator. The rule authors say it outright: the image-load event does not carry enough information, so go and look at the process creation event that spawned WMIC. /FORMAT: pointing at a URL or at a file outside %SYSTEMROOT%\System32\wbem is the finding. The DLL load on its own is not.

This is the entry I would hold up to anyone building detections. The rule is correct, the technique is real, and the event chosen to detect it is one layer too far from the decision. The fix was not a better rule. It was a note in the rule telling you where to look instead.

Documented at: SigmaHQ: WMIC Loading Scripting Libraries · LOLBAS: Wmic · ATT&CK T1220

6. Chrome and Dropbox sideload a DLL out of a temp directory

What fires. goopdate.dll loading from a path that is not Program Files, which is DLL search-order hijacking against Google's updater.

What it actually is. Google's updater, and Dropbox's installer, both of which stage into %LOCALAPPDATA%\Temp\GUM*.tmp and load the DLL from there. The rule needs three separate filters to stay usable, and its comment concedes the general case: many third-party Chromium applications ship this DLL, so baseline first.

The discriminator. The loading process and the directory's age. A GUM*.tmp directory created seconds earlier by a signed GoogleUpdate.exe is an update. The same DLL next to an unsigned executable, or in a directory that has been there since Tuesday, is not.

Documented at: SigmaHQ: Potential Goopdate.DLL Sideloading · ATT&CK T1574.001

How often does a public rule tell you any of this?

Every entry above exists because somebody wrote the false positive down. That is not the norm, and the gap is measurable rather than a matter of opinion.

Counting the falsepositives: block across the SigmaHQ rules/ directory, on a copy of master taken on 9 September 2026:

rules
in rules/3,144
with no falsepositives: block at all22
whose entire answer is the single word "Unknown"1,294
whose entire answer is the single word "Unlikely"257

So a little under half, 1,551 of 3,144 or 49%, ship with no usable statement of what else they hit.

Reproduce it yourself:

$ git clone --depth 1 https://github.com/SigmaHQ/sigma && cd sigma
$ find rules -name '*.yml' | wc -l
3144
$ find rules -name '*.yml' -exec perl -0777 -ne \
    'print "$ARGV\n" if /^falsepositives:\n\s+- (Unknown|Unlikely)\n(?!\s+- )/m' {} \; | wc -l
1551

The lookahead matters: it requires the non-answer to be the only entry, so a rule that says "Unknown" and then lists three real ones is not counted.

The number is not an indictment of the project. SigmaHQ takes community contributions across thousands of rules, "Unknown" is an honest answer when it is true, and an honest "Unknown" is better than a confident guess. The point is what it means for you: for roughly half of the public rulebase, the false-positive research is homework that has not been done, and if you deploy those rules as-is, you are doing it in production with your own analysts' nights.

Send one in

This is entry one of a running series, and the format wants examples from more estates than mine. If you have an alert that turned out to be the software working, post it in the community with the rule that fired, what it actually was, and the discriminator you landed on. It can go in the next one, with attribution if you want it.

Two things make an entry usable: it has to be reproducible by somebody else, and the discriminator has to be a real query rather than "we tuned it out".

Sources: SigmaHQ ruleset, master branch as of 9 September 2026, linked per entry above. Microsoft product documentation and MITRE ATT&CK linked inline. The count in the table was derived from the ruleset by the method shown.

Every false positive described here is one that the rule's own authors documented, or that follows directly from published vendor behaviour. None of it is drawn from a client environment, and no incident data informed it. The discriminators are proposed from the documented mechanism and are a starting point for your own tuning rather than tested thresholds.

Corrections and additions are welcome: this is a working document. Get in touch, or post a case of your own in the community.

Discussion

Guidelines

Sign in to comment. Corrections and additions are the point: this is a working document.