Hey everyone! 👋 I've been spending a lot of time lately tuning our QRadar rules to be more surgical, especially around the tricky area of detecting lateral movement. You know the struggleβyou write a rule, and suddenly you're drowning in false positives from admin traffic, backup jobs, or legitimate automation. I wanted to share a layered approach I've built that has significantly cut down the noise while still catching the scary stuff.
The core idea is to not rely on a single, overly-broad rule. Instead, we create a logical chain where events must satisfy multiple, increasingly specific conditions. This is especially useful for spotting things like SMB/WMI connections between workstations (which is rarely good). Here's my step-by-step breakdown:
**Step 1: Build a foundational "allow list" Reference Set.**
First, I created a Reference Set named `Known_Lateral_Communication_Sources`. This is key for reducing false positives. I populate it with the IPs of systems that *legitimately* touch many others, like:
* Patch servers
* Centralized backup servers
* Monitoring/NMS systems
* Domain Controllers (for certain protocols)
Any event originating from these IPs will be filtered out early.
```sql
-- Example query to populate the Reference Set from historical data (run once).
SELECT DISTINCT sourceip AS Source
FROM events
WHERE LOGSOURCENAME(logsourceid) LIKE '%Windows%' AND username IN ('BACKUP_ADMIN', 'MONITORING_ACCT')
GROUP BY sourceip
LAST 7 DAYS
```
**Step 2: The "Broad Net" Rule (Low Threshold, High Confidence).**
This is your initial filter. It fires on events that are *capable* of being used for lateral movement (e.g., "Windows Logon Success" or "SMB Session Established").
* **Rule Condition:** `Event Name` equals `'Windows Logon Success'` OR `'SMB Session Established'`.
* **Response:** `Add to Offense` and `Add to Custom Rule Property` (we'll use this property in the next layer).
* **Test:** Enable it briefly to ensure it captures the raw events. The offense volume will be highβthat's expected.
**Step 3: The "Layered Filter" Rule (The Brains).**
This rule only looks at offenses created by the "Broad Net" rule above and applies stricter logic.
* **Rule Condition:**
1. Offense was created by the **"Broad Net"** rule.
2. `Destination IP` is NOT in the `Known_Lateral_Communication_Sources` Reference Set. (Filters out known-good.)
3. `Source IP` and `Destination IP` belong to different `Network` segments (e.g., `User Subnets` vs. `Server Subnets`). This is crucial!
4. `Username` is NOT one of your known service accounts.
5. (Optional) `Peak Hour` is FALSE (if you want to ignore business hours).
* **Response:** `Add to Offense` (of the existing offense), `Set Severity to ELEVATED`, and `Annotate Offense`.
* **Test:** Now, an offense only grows if the activity is cross-segment, uses a non-service account, and doesn't come from a known management host.
**Why this layered approach works:**
* **Flexibility:** You can tune each layer independently. The allow list (Reference Set) is easy to maintain.
* **Transparency:** The offense shows the complete storyβthe initial event and why it was flagged by the filter rule.
* **Performance:** The first rule is simple. The second, smarter rule only runs on already-created offenses, not all events.
A final pitfall to avoid: Remember to regularly review and update your `Known_Lateral_Communication_Sources` Reference Set! As your infrastructure changes, so should your allow list. I've set a calendar reminder to do this quarterly.
I'd love to hear how others are tackling this. Have you used similar layered techniques for different use cases, like data exfiltration?
βB
Backup first.
This is a solid foundational step, but I'm concerned about the static nature of that reference set. The administrative IP list you're building is a decent first pass filter, but it's only effective if it's treated as a living artifact. If your patch server gets a new IP from DHCP or someone deploys a new, undocumented monitoring host, you've now introduced a blind spot.
You'll also want to consider the behavioral component. A domain controller making a WMI call to a single workstation for Group Policy processing is normal. That same domain controller initiating SMB connections to thirty different workstations in a five minute window is a very different story, even from an allowed IP. Your layered approach will need a subsequent step that looks at connection velocity and fan-out, irrespective of the source list.
How are you managing the lifecycle of that `Known_Lateral_Communication_Sources` set? Is it manually updated, or are you pulling it from a CMDB or infrastructure-as-code repository? Manual lists decay rapidly.