Security Engineering · Network Security
Detecting Periodic Beacons in Flow Telemetry
Why fixed-interval check-ins are visible in timing even when the payload is encrypted, how jitter and distribution shape change the test, and where the statistical approach fails on sparse data.
Malicious software that reaches back to its operator needs to do so repeatedly, and the simplest way to do that is on a timer. The payload is encrypted, the destination is a domain that resolves to a rotating address, and the traffic volume is negligible. What remains observable is that connections happen at regular intervals. Detecting that regularity is a statistical problem, and it has a specific set of failure modes that make it much less reliable than a naive periodogram suggests.
Why the timer is the signal
A beacon is a short outbound connection, repeated, carrying a request and a small response. If the implementation used a fixed sleep between attempts, the inter-arrival times form a near-constant sequence. Real implementations rarely do exactly that: they add jitter to avoid a distinctive signature, they back off after failures, and they resume after the host sleeps or the network drops. Each of those mechanisms degrades periodicity in a way that the detector must model or lose the signal.
There is a counter-pressure the attacker cannot easily remove. A beacon that fires too rarely makes command and control sluggish, and a beacon that fires too often is easy to see. Practical intervals land in the range of tens of seconds to hours, with the shorter end used for interactive sessions and the longer end for persistence checks. That range is wide, which means a detector must scan many candidate periods rather than test one.
The other constraint is volume. A beacon generates one flow record per check-in, and flow records are subject to the cache timeouts described in Flow Records and Traffic Baselining. A record’s start time is the time the first packet of the flow was seen, so the interval between records is the interval between first packets, not between connections, provided the flows do not overlap. That is a reasonable assumption for a beacon that completes and closes before the next one starts, and a bad one for anything that keeps a connection open.
The measurement problem: a handful of points
The fundamental difficulty is sample count. A beacon firing every ten minutes produces six events per hour, and a day of observation gives 144 events: enough for a period estimate, not enough for a sharp spectral estimate. A beacon firing every six hours gives four events per day. Any test that requires dozens of cycles within the observation window cannot see the slow case at all.
This is why detectors do not run a Fourier transform on the arrival times and look for a peak. With n samples, the frequency resolution of a periodogram is on the order of the total window length, and the variance of the estimate is large relative to the signal unless n is large. A sparse event stream also has a broadband spectrum by construction: a sequence of near-equal intervals produces a peak, but the same sequence with two missing events does not.
The workable alternative is to test a specific hypothesis. Given candidate period p, fold the timestamps modulo p and ask whether the folded values cluster. Under a random arrival process the folded values are uniform over the interval; under a periodic process they concentrate near a single phase. The concentration is measured with a circular statistic, the mean resultant length of the unit vectors at angles 2πt/p, which is near zero for uniform phases and near one for a tight cluster. Its cost is linear in the number of events per candidate period, and it tolerates small samples because the null expectation is itself small: for n uniformly distributed events the expected resultant length is about the square root of π/(4n), which is roughly 0.36 at six events and 0.09 at a hundred. A threshold therefore has to be set against that null for the observed count, not as a fixed constant.
Scanning candidates is the expensive part. A range from a minute to a day at one-minute granularity is 1440 candidates, and testing each over every source–destination pair in a large environment is quadratic in the wrong places. Practical implementations reduce the candidate set by deriving it from the data: the median inter-arrival time, and the strongest few peaks in a coarse histogram of intervals, give a handful of candidates per pair rather than a dense sweep.
Jitter, and what it costs the attacker
Jitter is usually described as adding a uniform random offset of some fraction of the interval. If the offset is a fraction j of the period, the folded phases spread over j of the circle, and the mean resultant length follows the magnitude of a sinc function of that width: about 0.98 at ten per cent jitter and about 0.64 at fifty per cent. Ten per cent jitter therefore costs the attacker almost nothing, because the margin over the null expectation stays large.
Large jitter is a different bargain. It makes the channel less responsive and makes the timing of the next check-in unpredictable to the operator as well, which is a real operational price. It also does not hide the count of connections. If the jitter is large, the aggregate number of connections to a destination in a window becomes the signal instead: a host that contacts one destination a fixed number of times per hour, every hour, for days, is anomalous regardless of the phase.
The two tests are complementary and are usually run together: phase concentration catches tight periodicity, and per-window count stability catches loose periodicity. The second tolerates jitter better and is less specific, because legitimate polling produces it too.
Distinguishing a beacon from a poller
Monitoring daemons, software update checks, licence validation, and telemetry exporters all poll on timers, and their traffic is indistinguishable from a beacon at the timing layer. Every real environment contains hundreds of them, and they dominate any alert list built on periodicity alone.
The discriminators that work are not statistical. The destination’s classification is the strongest: a known vendor endpoint is different from an unclassified domain, and the domain’s age and infrastructure are external facts that timing cannot supply. The client population is the second: a poller runs on every host of a fleet, while a beacon appears on one host or a small set, and a detector that aggregates by destination sees a fleet-wide pattern as one cluster and a beacon as an outlier. The payload size distribution is the third: pollers tend to have consistent request and response sizes, and a beacon that carries commands has a heavier tail on the response side.
That last point is where flow records stop being sufficient. Byte counts per flow are available, but the direction of the larger side is often ambiguous when the exporter aggregates. The signal exists in the packet lengths, which flow export discards by design. A deployment that needs it must add a packet sampling channel alongside flow export, and reconcile the two, since sampling gives length distributions and export gives complete flow coverage.
When the test fails
Sparse history. A pair with fewer than five observed events cannot be tested for phase concentration in any meaningful way. The detector either ignores it, which is where slow beacons live, or uses the count-stability test, which needs a baseline the pair does not have.
Timeouts splitting flows. If a check-in’s connection outlives the exporter’s inactive timeout, it appears as multiple records separated by a fixed offset, which manufactures apparent periodicity in traffic that has none. The artefact is a period equal to the timeout, and it will appear on many pairs at once, which is at least a visible clue that the data is wrong.
Clock and export delay. Record timestamps come from the exporter’s clock, and exports are batched. Both introduce a constant offset that does not affect interval analysis, and a variable delay that does. Under load, export batching can quantise timestamps to the batch interval, and that quantisation appears as periodicity at the batch rate. Collectors should record both the flow start time from the record and the receive time, and analysis should use the former.
Multi-stage beacons. An implant that contacts a fast channel for commands and a slow channel for liveness produces two independent periodicities from one host, each with few events. Neither is individually significant; the joint observation that one host has two distinct periodic destinations is significant. This is an argument for scoring hosts rather than pairs, and it is also why the aggregate view matters more than any single detection.
What the output is for
A periodicity score is a ranking, not a verdict. Its practical value is in prioritisation: it moves a small number of host–destination pairs to the front of an investigation queue, and it does so using metadata that is already being collected for other reasons. The cost of being wrong is an analyst’s time; the cost of not having it is that a low-volume channel is invisible against a background of bulk traffic.
The technique also composes with the others in this cluster. Query timing in Detecting DNS Tunnels from Query Structure is the same measurement applied to a different protocol, and the reassembly and normalisation layer in Multi-Pattern Matching in Network Intrusion Detection supplies the content evidence that timing cannot. Neither alone identifies a compromised host; the combination of a periodic destination, an unusual zone, and a matching signature does.
References
- RFC 7011: Specification of the IP Flow Information Export (IPFIX) Protocol — IETF
- Periodicity Detection in Time Series Databases — Elfeky, Elmagarmid, Aref; IEEE TKDE, 2005
- Statistical Analysis of Circular Data — N. I. Fisher; Cambridge University Press