Every SOC has the rule nobody reads. Deleting it loses coverage; leaving it burns analyst hours and teaches people to auto-close. Here is the loop for repairing one, with numbers.
Our patient is a deliberately broad LOLBin rule:
title: Suspicious Rundll32 Execution
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith: '\rundll32.exe'
condition: selection
level: medium
Over 30 days it produced 412 alerts. One was a true positive (a purple-team execution); 411 were closed as benign. Precision is 1/412, about 0.2%.
Step 1: count before you touch anything
You cannot tune what you have not stacked. Group the alerts by the fields that vary and look at the top of the list:
index=windows EventCode=1 Image="*\\rundll32.exe"
| stats count by ParentImage, CommandLine
| sort - count
In most estates three patterns dominate: shell32.dll,Control_RunDLL launched from explorer.exe (Control Panel), printui.dll,PrintUIEntry (printer setup), and davclnt.dll,DavSetCookie (WebDAV access).
Step 2: filter the specific benign, not the general case
Name the exact benign behavior, and pin each filter to context the attacker does not fully control - parent process, full image path, host group - as well as to the command line:
detection:
selection:
Image|endswith: '\rundll32.exe'
filter_control_panel:
ParentImage|endswith: '\explorer.exe'
CommandLine|contains: 'shell32.dll,Control_RunDLL'
filter_printing:
Image: 'C:\Windows\System32\rundll32.exe'
CommandLine|contains: 'printui.dll,PrintUIEntry'
condition: selection and not 1 of filter_*
The anti-pattern is CommandLine|contains: 'printui.dll' on its own. A command line is an attacker-controlled string, so a filter keyed only on a substring is a filter the attacker can simply type. Every exclusion should require at least one field they have to work to fake.
Step 3: raise specificity, don't just subtract noise
Filters remove known-good. Specificity is what actually buys precision. Add the attribute that made the behavior suspicious in the first place - here, a module loaded from a user-writable path:
selection:
Image|endswith: '\rundll32.exe'
CommandLine|contains:
- '\AppData\Local\Temp'
- '\AppData\Roaming'
- '\Users\Public'
- '\Windows\Temp'
Step 4: prove you did not lose the catch
This is the step people skip. Replay the tuned rule over the same 30 days of retained data and over the event set containing your known true positive. In our example alerts fall from 412 to 18, the purple-team execution still matches, and precision moves from 0.2% to roughly 6% with recall unchanged on the behavior you tested.
If the true positive stops firing, the filter was too broad - narrow it and replay again. A tuning change you cannot replay is a guess.
Step 5: make the change durable
- The filter lives in the rule file in version control, not as a hand-edited exception in the SIEM console.
- Record what you excluded and why under
falsepositives:, so the next engineer does not "fix" it back. - Set a review date. Benign patterns change whenever the estate changes.
- If a rule still cannot reach useful precision, don't delete it - drop its
leveland route it to a hunting dashboard instead of the paging queue. Weak signals are useful as context and harmful as alerts.
