Case Study 1: Hunting the Beacon at Meridian

"No alert fired. That's exactly why I'm worried." — Priya Nair, IR & Threat Hunting lead, Meridian Regional Bank (constructed)

Executive Summary

A financial-sector information-sharing group publishes an advisory: a capable adversary is compromising trusted software-update mechanisms to gain initial access, then beaconing out over jittered HTTPS in a way designed to evade signature-and-indicator detection. Meridian runs exactly the class of server-management software named in the advisory, and not a single alert has fired. This case study follows IR lead Priya Nair and junior analyst Theo Brandt as they run a hypothesis-driven hunt for SolarWinds-style command-and- control beaconing — forming a behavioral hypothesis, scoping the data, writing the hunt query, triaging three near-identical "regular beacon" hosts down to the one that matters, and converting the find into a durable Sigma detection. You will watch every idea from the chapter become an action: the pyramid of pain explains why the advisory's indicators are nearly worthless; threat intelligence becomes a hypothesis rather than a blocklist; the hunt loop runs end to end; and a discovered adversary is handed cleanly to incident response. The scenario, logs, and figures are constructed for teaching (Tier 3); the techniques, ATT&CK IDs, and detection patterns are real.

Skills applied: translating threat intel into a hunt hypothesis; ATT&CK technique mapping; behavioral (beacon) detection vs. indicator matching; writing and running a hunt query; triage against a baseline; converting a finding into a Sigma rule (detection-as-code); the detection→hunting loop; clean hand-off to incident response.

Background

Meridian Regional Bank's security program has matured fast in the months since the phishing near-miss. The SIEM is live (Chapter 21), ingesting and normalizing logs from across the bank; the network-monitoring layer (Chapter 10) put a Zeek sensor on the data-center egress, so every outbound connection from the server tier is logged with source, destination, port, and timestamp in conn.log. Marcus Reyes's SOC works a real alert queue. But Priya has been pushing Dana, the CISO, on a harder point: the queue only catches what someone already wrote a rule for. "We're good at the attacks we've imagined," she says in a program review. "I want to know about the ones we haven't."

The catalyst arrives as a PDF. Meridian belongs to a financial-sector ISAC (Information Sharing and Analysis Center), and the ISAC distributes an advisory, marked TLP:AMBER (share within the org, not publicly), describing an active campaign:

Adversary gains initial access by compromising a trusted software-update mechanism (a supply-chain compromise). The implant remains dormant for up to two weeks, then establishes command-and-control over HTTPS to attacker infrastructure, using a jittered interval (roughly regular, with added randomness) to blend into normal enterprise traffic. Known infrastructure rotates frequently. Indicators below are low-confidence and likely already abandoned. [Three domains, two IPs, one file hash follow.]

Theo's first instinct is the natural one, and it is wrong: load the three domains and two IPs into the SIEM as a blocklist and call the bank protected. Priya stops him — and the stop is the lesson.

🛡️ Defender's Lens: "Read the advisory's own warning," Priya tells Theo. "It says the indicators are low-confidence and likely abandoned. Of course they are — by the time a campaign is written up and shared, the adversary has rotated infrastructure. Those domains and IPs are the bottom of the pyramid of pain. We'll load them, because it costs us nothing, but they will not save us. What can't the adversary change without giving up their objective? They have to beacon home. That's the technique. That's what we hunt for."

She and Theo also do the relevance triage from §22.3: does this campaign plausibly target Meridian? Yes — it hits the financial sector, and Meridian runs SolarWinds-style server-management software in its on-prem data center, exactly the kind of trusted, widely-deployed, internet-adjacent product the advisory describes being weaponized. This is not an industrial-control-system worm they can file away. It is on target. The hunt is justified.

The Hunt

Phase 1 — Hypothesize (and map to ATT&CK)

A hunt is only as good as its hypothesis, so Theo writes one down explicitly before touching any data — specific, testable, grounded in the advisory, and mapped to ATT&CK so it ties into Meridian's coverage:

HUNT HYPOTHESIS  (Meridian, HUNT-2026-014)
---------------------------------------------------------------
IF an adversary compromised one of our server-management or
server-tier hosts via a trusted update
   [T1195.002 Supply Chain Compromise: Compromise Software Supply Chain]
AND is now running command-and-control
   [T1071.001 Application Layer Protocol: Web Protocols]
   [T1573    Encrypted Channel — it's HTTPS]
THEN we would expect to observe:
   a host in the SERVER network tier
   making REPEATED, NEAR-REGULAR (low-jitter) outbound
   HTTPS (tcp/443) connections
   to a SINGLE EXTERNAL destination
   that the host has no legitimate business reason to contact.
DATA SOURCE: Zeek conn.log (data-center egress) / proxy logs.
DISPROOF: no server-tier host shows regular outbound HTTPS to an
   unexplained single external destination beyond known-benign ones.
---------------------------------------------------------------

The hypothesis does real work. It names the behavior (regular outbound HTTPS from a server to one external host), not the adversary's specific infrastructure — so it will catch the campaign even though every indicator in the advisory is stale. It names the data source, so the next step is concrete. And it states what disproof looks like, so the hunt can end in a defensible "no" rather than dragging on forever. Priya reviews it and adds one refinement: "Filter to new or unexplained destinations during triage. Plenty of our servers beacon to legitimate things — that's the noise we have to see through."

Phase 2 — Scope the data

Does Meridian have the data to test this? Theo confirms three things before writing a query:

  1. Coverage of the right traffic. The Zeek sensor sits on the data-center egress (Chapter 10's design), so it sees outbound connections from the server tier to the internet. Good — that is exactly the traffic the hypothesis is about.
  2. The fields he needs. conn.log records id.orig_h (source IP), id.resp_h (destination IP), id.resp_p (destination port), and ts (timestamp). From source IP he can derive the source zone (server vs. workstation vs. branch) using Sam's network documentation; from the destination he can derive whether it is internal or external. He has what he needs to reconstruct per-pair connection timing.
  3. Enough history. Retention holds 30 days of conn.log. The advisory says the implant may stay dormant up to two weeks before beaconing, so 7 days of look-back is a reasonable first pass and 30 is available if the first pass is clean.

This step is not a formality. Had any of the three failed — no egress sensor, no timestamps, no retention — the hunt would have immediately surfaced a visibility gap, which is itself a finding worth escalating (you cannot hunt for what you cannot see). Meridian's earlier investment in network monitoring is what makes this hunt possible at all.

⚠️ Common Pitfall: Skipping the data-scoping step and writing the query first. A hunter who queries before confirming the data exists and is complete can spend a day "finding nothing" and conclude wrongly that the environment is clean — when in fact the relevant traffic was never being captured. "No results" from incomplete data is not the same as "no adversary." Always confirm you could see the thing before concluding you don't.

Phase 3 — Query and analyze

Theo translates the hypothesis directly into a hunt query against the Zeek connection data. He uses SIEM pseudo-SQL; the same logic compiles to SPL or KQL on whatever Meridian runs:

-- HUNT-2026-014: regular outbound beacons from the server tier
-- (Meridian, illustrative; run only in the authorized SIEM)
SELECT  src_ip,
        dest_ip,
        COUNT(*)                          AS conn_count,
        COUNT(DISTINCT dest_ip)           AS distinct_dsts,
        ROUND(AVG(inter_arrival_seconds))   AS mean_interval,
        ROUND(STDDEV(inter_arrival_seconds))AS jitter_stddev
FROM    zeek_conn
WHERE   src_zone       = 'server'          -- server tier only (hypothesis)
  AND   dest_category  = 'external'         -- leaving the org
  AND   dest_port      = 443                -- HTTPS
  AND   _time > NOW() - INTERVAL '7 days'
GROUP BY src_ip, dest_ip
HAVING  COUNT(*) >= 100                      -- chatty enough to be automated, not human
   AND  STDDEV(inter_arrival_seconds) < 60   -- LOW jitter = regular = beacon-like
ORDER BY jitter_stddev ASC;                  -- most regular first

Each clause encodes a piece of the hypothesis: src_zone='server' and dest_category='external' and dest_port=443 narrow to server-tier outbound HTTPS; grouping by the (src_ip, dest_ip) pair models "one host beaconing to one destination"; COUNT(*) >= 100 keeps only automated chatter (a human browsing does not make a hundred connections to the same host at a regular interval); and STDDEV(...) < 60 is the behavioral heart — it keeps only regular beacons, the statistical fingerprint that survives the adversary's jitter. This is beacon_score from Chapter 10, written in SQL. Theo runs it against the authorized SIEM and gets four rows:

src_ip       dest_ip          conn_count  distinct_dsts  mean_interval  jitter_stddev
10.20.5.40   203.0.113.77     336         1              120            9      <- ???
10.20.5.51   198.51.100.9     288         1              600            7      <- ???
10.20.5.11   <Windows Update> 412         1              300            48
10.20.5.22   <vendor SaaS>    288         1              600            55

Four hosts show regular outbound HTTPS beaconing. The query did its job — it cut the data-center's millions of connections down to four candidate beacons — but it did not tell Theo which are malicious. That is the next, and hardest, step.

Phase 4 — Triage

This is where hunting becomes an art, and where Meridian's prior baselining pays off. All four rows are "regular beacons." The difference is what they beacon to, and whether that is explainable.

Theo works each row against the asset/vendor inventory and resolves each destination:

  • 10.20.5.11 → Windows Update. The destination resolves to Microsoft's update infrastructure. The source is a Windows server checking for patches every five minutes — expected, benign, known. Dismiss.
  • 10.20.5.22 → vendor SaaS. The destination is a monitoring vendor in Meridian's documented vendor list; the source runs that vendor's agent, which beacons telemetry every ten minutes. Documented, benign. Dismiss. (Note both benign beacons had higher jitter — 48 and 55 — because legitimate update and telemetry checks tolerate sloppy timing; the malicious ones were more regular.)
  • 10.20.5.51198.51.100.9. This one resists easy dismissal at first. The destination is external and not obviously in any vendor record. Theo digs: the IP belongs to a certificate-authority OCSP responder (a service browsers and servers contact to check certificate revocation), and 10.20.5.51 is a reverse proxy that legitimately performs frequent revocation checks. After verifying with Sam, Theo dismisses it — but he documents the reasoning, because "looked suspicious, turned out benign" is exactly the kind of finding that should be baselined so the next hunter doesn't re-investigate it.
  • 10.20.5.40203.0.113.77. Everything about this row deepens the suspicion. Sam confirms 10.20.5.40 is the server-management application server — the SolarWinds-style product named in the advisory's class. The destination 203.0.113.77 belongs to a generic hosting provider; the domain it resolves to was registered three months ago; and it appears in no Meridian asset record, no vendor contract, and no documented integration. A server-management product has no legitimate reason to contact a freshly registered host at a generic provider every two minutes with clockwork regularity. The IoC check is the final nail: Theo runs 203.0.113.77 against the advisory's indicators — and it is not on the list (the advisory's indicators were stale, exactly as predicted), but it is on a community threat feed his TIP enriched. The behavior found it; the indicator merely confirmed it.
TRIAGE RESULT  (HUNT-2026-014)
  10.20.5.11  -> Windows Update          BENIGN  (known, documented)
  10.20.5.22  -> vendor SaaS telemetry   BENIGN  (documented vendor)
  10.20.5.51  -> CA OCSP responder       BENIGN  (revocation checks; documented + baselined)
  10.20.5.40  -> 203.0.113.77            MALICIOUS (server-mgmt host, unexplained new
                                          external dest, every 120s, low jitter) ◄── FINDING

🔄 Check Your Understanding: Three of the four beacons were benign and the malicious one was not the most or least chatty. What specific facts let Theo separate 10.20.5.40 from the benign three — and what would have happened if Meridian had no asset/vendor inventory and no prior baselining? (Hint: without a notion of "normal," all four rows look identical, and a hunter either flags all of them — crying wolf — or learns to ignore regular beacons entirely, including the real one.)

There is a deeper lesson buried in the jitter numbers, and it is worth pausing on because it inverts a beginner's intuition. The two malicious-looking low-jitter rows (10.20.5.40 at stddev 9, 10.20.5.51 at stddev 7) were actually more regular than the two known-benign update/telemetry beacons (stddev 48 and 55). A naive hunter, told "beacons are regular," might assume the most regular traffic is the most suspicious and the sloppiest the most benign — and would be exactly half wrong. Legitimate update checks and telemetry agents are often sloppier in their timing than C2, because they don't care about precision: they fire "every five minutes-ish," retrying on failure, drifting with system load. A disciplined C2 implant, by contrast, may beacon with near-machine precision or may deliberately add heavy jitter to look sloppy — the adversary controls it. So regularity alone is necessary but not sufficient: it gets a connection onto the candidate list, but only contextwhich host is beaconing and to where — turns a candidate into a finding. Both 10.20.5.40 and 10.20.5.51 were tightly regular; what separated them was that one talked to a documented CA revocation responder and the other to a three-month-old domain in nobody's records. The timing got them onto the list; the destination decided their fate.

This is why Theo's triage discipline of documenting the benign matters as much as flagging the malicious. He did not simply discard 10.20.5.51 (the OCSP responder) once he cleared it; he wrote down why it was benign and added it to Meridian's baseline of known-good server beacons. The next hunt — or the automated detection this hunt will produce — should not re-flag it and burn another analyst's afternoon. A mature hunting practice accumulates this institutional knowledge of "normal," so that each hunt starts from a richer baseline than the last and the team spends its scarce attention on genuinely new anomalies. The benign findings are not wasted work; they are the baseline being built.

📟 War Story: A constructed but representative composite. A SOC at another institution ran a similar beacon hunt and found a server-tier host beaconing every 60 seconds with near-zero jitter to an external host. The analyst, certain it was C2, escalated to a full incident — war room, vendor on the phone, containment planning. Eight hours later, the "C2" turned out to be a misconfigured internal monitoring probe that an engineer had pointed at a cloud-hosted health-check endpoint, beaconing with machine precision exactly because it was a machine doing health checks. The lesson is not "don't escalate" — the behavior genuinely warranted investigation. The lesson is that the triage step (enrich the destination, check the asset records) must come before the war room, and that an asset/vendor inventory good enough to immediately answer "is this destination ours?" turns an eight-hour fire drill into a five-minute dismissal. Meridian's inventory is what let Theo go the other way fast — confirming malice in minutes rather than chasing a ghost for hours.

Phase 5 — Conclude

The hypothesis is confirmed (pending formal IR confirmation): a server-tier host — specifically the server-management application server, exactly the asset class the advisory warned about — exhibits the predicted C2-beacon behavior to an unexplained, recently-registered external destination. The hunt has found, by hypothesis and query alone, the thing no alert ever caught.

Crucially, Theo does not start remediating. He does not log into 10.20.5.40, does not block the IP at the firewall, does not reboot the host. Two reasons, both from the chapter's framing of the hand-off: first, finding an adversary and evicting one are different jobs with different risks — a clumsy remediation can tip off the adversary, destroy volatile evidence, or break a production banking system; second, this is now an incident, and incidents follow the incident-response process (Chapter 24), which begins with preserving evidence and making containment decisions deliberately. Theo's job was to find it. He found it. He escalates to Priya, who opens an incident.

🛡️ Defender's Lens: Re-read what the hunt did not need. It needed no hash, no known-bad IP, none of the advisory's stale indicators. It needed a hypothesis about behavior — servers shouldn't beacon to the internet — and the data to test it. That is the entire reason hunting answers the stealthy adversary: you are not matching what the adversary is (which they control), you are looking for what they must do (which they cannot avoid). Sunburst's real-world hunters found it the same way.

Phase 6 — Operationalize

The hunt is not finished when the incident opens. Its final, defining step is to make sure Meridian never has to hand-hunt this again. Theo and Priya take the query that found the beacon and turn it into the durable behavioral Sigma rule from §22.4:

title: Regular Outbound Beacon from a Server-Class Host
id: 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: >
  A server-tier host making repeated, low-jitter outbound HTTPS connections
  to a single external destination it has no documented reason to contact —
  the signature of C2 beaconing. Born from HUNT-2026-014.
references:
  - https://attack.mitre.org/techniques/T1071/001/
tags:
  - attack.command_and_control
  - attack.t1071.001
logsource:
  category: proxy            # Zeek conn.log / NetFlow
  product: zeek
detection:
  selection:
    src_zone: 'server'
    dest_category: 'external'
    dest_port: 443
  timing:
    # analytic job: per (src,dest) pair over 6h, COUNT >= 100 AND jitter_stddev < 60
    # AND destination NOT IN (asset_inventory + vendor_allowlist)
  condition: selection | beacon_score(timestamps) >= threshold and dest_unknown
falsepositives:
  - Software update checks, telemetry agents, OCSP/CRL revocation checks, and
    SaaS keep-alives — suppressed via the asset/vendor allowlist enrichment.
level: high

They also file a visibility improvement: the triage would have been faster if outbound destinations were automatically enriched against the asset/vendor inventory at ingest, so "server talking to an unknown external host" surfaced without a human cross-referencing by hand. And they update Meridian's coverage map: "Command and Control → Web Protocols (T1071.001)" moves from a red (blind spot) to a green (covered) cell, and "Initial Access → Supply Chain Compromise (T1195.002)" is flagged as the next gap to close. The hunt did three permanent things: it found an adversary, it produced a detection so the next beacon is caught for free, and it shrank a blind spot on the coverage map. That is a hunt.

Aftermath: the loop closes

Step back and look at what just happened as a system, because the Meridian beacon hunt is a small, clean instance of the detection→hunting loop from §22.1 (Figure 22.1) — and seeing the whole cycle is what turns one lucky catch into an operating capability.

The cycle began with a gap in detection engineering. Meridian had a SIEM and correlation rules (Chapter 21), but none of them was written to catch "a server beaconing to a new external host on a regular interval" — that technique was a red cell on the coverage map, an acknowledged blind spot. No automated rule fired, and no automated rule could have, because no one had built one. This is not a failure of the SOC; it is the structural limit of anticipation-only detection. You cannot pre-write a rule for every technique, and the techniques you haven't covered are exactly where a capable adversary operates.

Hunting filled the gap manually and proactively. Priya did not wait for an alert that would never come. Prompted by threat intelligence (the ISAC advisory), she formed a hypothesis about behavior, and Theo tested it by hand against data the bank already collected. The hunt was, in effect, a human being running the detection that the rule engine couldn't — once, slowly, with judgment. That is the right tool for a technique you cannot yet automate: human attention, aimed precisely by a hypothesis.

And then the loop closed back to engineering. The hunt did not end at "we found it." Its final act was to hand the finding back to detection engineering as a durable, automated rule, so that the next beacon — from any server, to any unknown external host — fires an alert with no human needing to think to look. The red cell on the coverage map turned green. The blind spot the hunt exploited is now covered for free, forever, and the team's scarce attention is freed to hunt the next uncovered technique (Supply Chain Compromise, T1195.002, now flagged as the next gap). This is how a hunting program compounds: each hunt permanently raises the detection floor, so the team is always hunting at the frontier of what it cannot yet automate, never re-hunting what it already understands.

Notice, too, how every earlier chapter's investment showed up in this one hunt. The network monitoring from Chapter 10 supplied the Zeek conn.log data and the beacon_score concept. The SIEM from Chapter 21 supplied the query engine and the normalized data to run the query against. The asset and vendor inventory — begun all the way back in Chapter 1's first Project Checkpoint — supplied the "is this destination ours?" ground truth that made triage a five-minute job instead of an eight-hour fire drill. And the threat intelligence discipline from §22.3 supplied the hypothesis. A hunt is never a standalone act of genius; it is the moment all of a security program's prior investments are cashed in at once. An organization that has not built the data, the inventory, and the intelligence pipeline cannot hunt at all — it can only browse logs and hope. Meridian could hunt because Meridian had, chapter by chapter, built the substrate that hunting runs on.

Theo, three weeks past the most stressful afternoon of his short career, writes the after-action note that Priya asks every hunt to produce. It is two paragraphs: what the hypothesis was, what the query found, what detection now exists, and what the next gap is. It is unglamorous. It is also exactly the artifact that makes the next hunt faster and the SOC permanently smarter — the institutional memory that separates a team that hunts from a team that occasionally gets lucky.

Discussion Questions

  1. Priya stopped Theo from treating the advisory's indicators as the defense. Using the pyramid of pain, explain why loading the three domains and two IPs was nearly worthless against this adversary — and why it was still worth doing anyway.
  2. The hunt found the adversary through behavior (regular outbound beaconing) rather than any indicator. What does this tell you about the relative value of "operational" vs. "tactical" threat intelligence for a hunt? When would tactical indicators actually be the better tool?
  3. Three benign hosts and one malicious host all beaconed regularly. Triage depended entirely on knowing the environment's "normal." What specific prior investments (across this and earlier chapters) made that triage possible, and what would a hunt look like in an organization that lacks them?
  4. Theo explicitly did not remediate when he confirmed the beacon. Argue why this restraint is correct, and describe one concrete way that a junior analyst "just fixing it" could make the incident worse.
  5. The hunt ended by producing a Sigma rule and updating the coverage map. Why is this "operationalize" step more important, in the long run, than the single beacon it caught? What does a hunting program look like if every hunt skips it?

Your Turn

Pick a different ATT&CK technique relevant to a financial institution — for example, OS Credential Dumping (T1003), Scheduled Task persistence (T1053), or Exfiltration Over C2 Channel (T1041) — and run the full six-step hunt loop on paper. (1) Write a specific, testable, ATT&CK-mapped hypothesis using the chapter's template. (2) Name the data source that would answer it and state honestly whether a typical bank collects it. (3) Sketch the hunt query (SQL/SPL/KQL), annotating each clause with what it encodes. (4) Describe how you would triage hits — name at least one benign pattern you'd have to see through. (5) State a plausible conclusion. (6) Write the durable detection (a Sigma rule or its logic) and/or the visibility gap you would operationalize. Keep it to two pages. If you cannot name the data source in step 2, you have just discovered a blind spot — note it.

Key Takeaways

  • A hunt begins with threat intelligence reframed as a hypothesis, not a blocklist: the advisory's stale indicators were bottom-of-the-pyramid, but its techniques (supply-chain compromise + jittered C2) became a testable behavioral hypothesis.
  • Scope the data before querying. Confirm the relevant telemetry exists, has the needed fields, and has enough history — otherwise "no results" may just mean "no visibility," a finding in itself.
  • The hunt query encodes the hypothesis directly: narrow to the relevant traffic with cheap filters, then apply the behavioral analytic (beacon regularity / low jitter) that no field-match could express.
  • Triage is where baselining pays off. Several hosts beaconed regularly; only an asset/vendor inventory and prior baselining let the hunter separate the malicious beacon from benign update, telemetry, and revocation traffic. The malicious beacon was found by behavior; the indicator merely confirmed it.
  • Find, then hand off. The hunter confirms and escalates to incident response (Chapter 24) without remediating — preserving evidence and avoiding tipping off the adversary or breaking production.
  • Operationalize or it wasn't a hunt. The find became a durable Sigma detection (so the next beacon fires automatically) and shrank a blind spot on the ATT&CK coverage map. The lasting value of a hunt is the permanent improvement it leaves behind, not the single thing it caught.