Hunting in the Noise: Advanced Splunk Queries

Hunting in the Noise: Advanced Splunk Queries

Signature matching catches the lazy. Real adversaries live in the gap between “expected behavior” and “what actually happened.”
// TL;DR
Threat hunting in Splunk isn’t a magic | stats count. It’s a discipline of forming hypotheses, picking the right index, narrowing the time window, and reading what comes back without flinching. Below: the SPL patterns I actually run on real watch floors — lateral movement, beaconing, credential abuse, rare process trees — and notes on tuning so you don’t go blind.

// The Hunting Mindset

Detection engineering says: “tell me when X happens.” Hunting says: “I think Y is happening, prove me wrong.” Hunters start with hypotheses, not alerts. The Splunk query is the instrument; the hypothesis is the experiment.

A useful hypothesis is testable, time-bounded, and tied to a TTP. “Adversary is using scheduled tasks for persistence” beats “find weird stuff.”

// FROM THE WATCH FLOOR
The biggest skill jump in SPL isn’t learning more commands — it’s learning to narrow before you hunt. earliest=-24h, the right index, the right sourcetype. Hunting an entire estate at once is how you end up with 11 million events and zero answers.

// Pattern 1: Lateral Movement via Admin Shares

Looking for SMB activity to ADMIN$, C$, or IPC$ that wasn’t initiated by your imaging or patching tools. EventCode 5145 on Windows, with object_name filtering:

// Hunt: SMB lateral movement via admin shares index=wineventlog EventCode=5145 ObjectName IN (“\\\\*\\ADMIN$”,”\\\\*\\C$”,”\\\\*\\IPC$”) | eval src=mvindex(split(IpAddress,”:”),0) | stats dc(ObjectServer) as targets, count by src, SubjectUserName | where targets > 5 AND NOT match(SubjectUserName, “(?i)svc_|backup|sccm”) | sort – targets

The dc(ObjectServer) is the trick — one user reaching many servers’ admin shares in a short window is the fingerprint, not any single connection.

// Pattern 2: Beaconing Detection (Periodic Outbound)

C2 traffic looks boring on purpose. Steady intervals, similar byte counts, low entropy in domain names. We can find the regularity:

// Hunt: low-jitter beaconing index=proxy OR index=firewall action=allowed | bin _time span=1m | stats count by _time, src_ip, dest_host | stats count as buckets, avg(count) as avg_per_min, stdev(count) as jitter by src_ip, dest_host | where buckets > 30 AND avg_per_min > 0.5 AND jitter < 0.4 | sort – buckets

You’re filtering for hosts that talked to a destination on at least 30 different one-minute slices, with low standard deviation in frequency. That’s not a person browsing — that’s a scheduler.

// Pattern 3: Rare Parent-Child Process Trees

Signature-based detection misses LOLBins. Statistical rarity catches them. Anything spawning powershell.exe from winword.exe or excel.exe deserves a look:

// Hunt: Office spawning script interpreters index=edr sourcetype=process_creation parent_image IN (“*\\winword.exe”,”*\\excel.exe”,”*\\outlook.exe”) image IN (“*\\powershell.exe”,”*\\cmd.exe”,”*\\wscript.exe”,”*\\cscript.exe”,”*\\mshta.exe”) | stats count, values(command_line) as cmds by host, user, parent_image, image | sort – count

Pair this with a baseline: in a healthy enterprise this query should return near-zero on a normal day. When it doesn’t, you have something to chase.

// Pattern 4: Credential Abuse via 4624 + 4768

Logon type 3 (network) from many sources to one account in a short window is a classic credential-stuffing or pass-the-hash signature:

// Hunt: distributed network logons to single account index=wineventlog EventCode=4624 LogonType=3 | stats dc(IpAddress) as src_count, values(IpAddress) as srcs, count by TargetUserName | where src_count >= 10 | sort – src_count

// Tuning Without Going Blind

Every hunt that becomes a detection rule needs three things or it dies on contact with production:

  • An owner. If nobody’s name is on it, nobody will fix it when it drifts.
  • A defined false-positive class. “Vuln scanners cause LogonType 3 from many IPs” is a known FP. Document it; suppress it explicitly; revisit quarterly.
  • A threshold review schedule. Environments change. The hunt that worked at 5 hosts/minute is a wall of noise at 50.
// ANALYST’S NOTE
The single best way to reduce alert fatigue is not to write fewer detections — it’s to retire detections that have never produced a true positive in 90 days. They’re tax. Pay it down.

// Closing

SPL is just grammar. The thing that makes a hunter dangerous is the question they’re asking when they sit down at the search bar. Frame the hypothesis, narrow the data, and read the results like a detective — not a dashboard.

<< PREV: SIGNAL VS. NOISE NEXT: HUMAN ELEMENT >>
Scroll to Top