Post

Hunting C2 Beacons With Statistics

Beacons hide in normal-looking traffic. Here's how to use frequency and statistical analysis to find periodic C2 communication reliably.

Hunting C2 Beacons With Statistics

C2 beacon timing identified as a statistical deviation worth investigating

Malware doesn’t call home constantly. It calls home on a schedule, because a constant connection is expensive to maintain and easy to spot, while a quiet check-in every few minutes blends into the general hum of legitimate background traffic almost perfectly. That’s the whole premise behind beaconing, and it’s also the exact thing that makes it detectable if you stop looking at individual connections and start looking at patterns over time.

Signature-based detection mostly fails against beaconing because there’s nothing inherently malicious about a single HTTPS connection to an external IP. The malice is in the rhythm, not the request. Statistical analysis is what actually surfaces that rhythm.

Interval consistency is the first thing to measure, and it’s simpler than it sounds

The core idea: pull every connection from a given source host to a given destination over a time window say the last 24 hours and calculate the time delta between consecutive connections. Legitimate, human-driven traffic has messy, irregular intervals. Someone checking email doesn’t do it every 300 seconds on the dot. Malware beacons, even ones designed with jitter to avoid looking too clean, tend to cluster around a mean interval with a standard deviation that’s small relative to that mean.

A beacon with a base interval of five minutes and twenty percent jitter still lands the vast majority of its check-ins somewhere between four and six minutes apart. Plot that as a histogram and you’ll see a distinct clustering that random human behavior just doesn’t produce. Calculating the coefficient of variation standard deviation divided by mean across connection intervals per host-destination pair, and flagging anything with a suspiciously low coefficient combined with a reasonable connection count (ten or more in the window, to avoid noise from small samples), catches a lot of beaconing that pure volume-based rules miss entirely.

Byte size regularity is the underrated second signal

Interval analysis alone produces false positives some legitimate monitoring tools and health check services genuinely do beacon on regular schedules. What separates malicious beaconing from a legitimate heartbeat is usually the payload consistency combined with the interval, not the interval alone.

Malware beacons frequently send near-identical request sizes on check-ins with no new tasking a compressed status update that comes out to roughly the same byte count every time, maybe 512 bytes with small variance, until the operator issues a command and the response size spikes. Building a second statistical layer on top of interval analysis standard deviation of bytes-transferred per connection in that same host-destination pair and looking for low variance in both dimensions together cuts false positives dramatically compared to either signal alone. A legitimate NTP sync has regular intervals but predictable, protocol-defined byte counts too, so this isn’t a perfect filter, but combining both dimensions gets you a meaningfully shorter, higher-confidence list to actually investigate.

Jitter-aware detection beats naive threshold rules

Early beaconing detection approaches just looked for exact interval matches, which sophisticated malware defeats trivially by adding randomized jitter. The fix isn’t giving up on interval analysis it’s using a wider statistical lens instead of a rigid threshold. Fast Fourier Transform analysis on the connection timestamp series can reveal periodicity even through meaningful jitter, because the underlying frequency still shows up as a dominant peak in the frequency domain even when individual intervals vary quite a bit around it.

This sounds more complicated than it is to actually implement most SIEM platforms with any scripting capability, or a straightforward Python job pulling from your flow data, can run this analysis without needing a dedicated data science team. The output is a periodicity score per host-destination pair, and you set a threshold based on your own environment’s baseline rather than a generic industry number, because normal beacon-adjacent traffic volume varies a lot between a 200-person office and a 20,000-endpoint enterprise.

DNS and encrypted channels both leave the same statistical fingerprint

Beaconing doesn’t require HTTP or HTTPS specifically DNS-based check-ins, as covered in our DNS hunting piece, follow the exact same statistical logic, just applied to query timestamps instead of connection timestamps. The technique transfers directly: group by source host and queried domain, measure interval consistency, flag outliers relative to your baseline.

Encrypted traffic doesn’t defeat this approach either, and that’s the real value here TLS hides payload content, but it can’t hide connection metadata. Timing and size are visible regardless of encryption, assuming you’re capturing flow-level data rather than trying to inspect payload directly. This is part of why beaconing analysis has actually gotten more valuable as encryption adoption has gone up, not less a lot of the old payload-inspection techniques are dead ends against modern TLS, but timing-based statistical analysis works exactly the same whether the channel’s encrypted or not.

Building this into a standing analytic instead of a one-time exercise

The mistake teams make with beaconing detection is treating it as a manual investigation technique they pull out during an active incident, rather than a continuously running analytic. Given how cheap flow metadata is to retain compared to full packet capture, there’s not much reason not to run interval and byte-size consistency scoring across your whole environment on a rolling basis, surfacing the highest-scoring host-destination pairs to a queue for analyst review rather than waiting for a specific trigger.

Tune the thresholds against your own traffic for a couple of weeks before trusting the output every environment has its own mix of legitimate periodic traffic (health checks, sync jobs, telemetry agents) that needs to get baselined out first, or you’ll bury your analysts in false positives before the technique earns their trust.

This post is licensed under CC BY 4.0 by the author.