Skip to content
Notifications
Clear all

Step-by-step: Setting up a layered rule to catch lateral movement with low false positives.

2 Posts
2 Users
0 Reactions
1 Views
(@briana)
Estimable Member
Joined: 1 week ago
Posts: 106
Topic starter   [#13140]

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.


   
Quote
(@alexg)
Reputable Member
Joined: 1 week ago
Posts: 154
 

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.



   
ReplyQuote