Detect Statistical Beacon Jitter Analysis for C2 Detection via Network Flow Logs in Sumo Logic CSE
Modern C2 frameworks (Cobalt Strike, Sliver, Mythic, Brute Ratel) let an operator configure a malleable beacon profile with a sleep interval plus a jitter percentage so that outbound check-ins vary enough to defeat naive fixed-interval detections while still resolving, statistically, to a highly regular cadence. Publicly reported intrusions attributed to APT29, FIN7, and Wizard Spider have repeatedly involved Cobalt Strike or similar frameworks configured with low-jitter (single-digit percent) HTTPS beacon profiles that blend with normal browser traffic on ports 80/443/8080/8443. Because the destination is frequently a freshly registered or short-lived domain with no established reputation, and TLS encrypts the payload, defenders cannot rely on content inspection or domain reputation alone. This detection instead applies time-series statistics directly to network flow/session logs (firewall, proxy, or Zeek connection records) rather than endpoint process telemetry: for every observed (source, destination, port) tuple it reconstructs the sequence of connection timestamps, computes the coefficient of variation (CV = standard deviation / mean) of the inter-connection intervals, and combines that with the CV of the outbound byte-count per session. Legitimate interactive or bursty application traffic produces a high CV (irregular timing, variable payload size); a malleable-profile C2 beacon produces a low CV on both axes because the sleep+jitter algorithm is bounded and the check-in request is usually a fixed-shape HTTP GET/POST. This detection deliberately runs against network-layer session/flow logs rather than endpoint agent telemetry, which makes it a good complement to the endpoint-focused beaconing heuristics already covered on the parent T1071.001 page: it also catches beaconing from devices with no EDR agent (network appliances, IoT, unmanaged BYOD, servers running third-party software) as long as their traffic transits a monitored firewall, proxy, or SPAN/TAP point.
MITRE ATT&CK
- Tactic
- Command and Control
Sumo Detection Query
_sourceCategory="network/firewall"
| json field=_raw "src_ip", "dst_ip", "dst_port", "bytes_out" as src_ip, dst_ip, dst_port, bytes_out
| where dst_port in (80, 443, 8080, 8443)
| timeslice 1s
| stats count AS SessionCount, avg(bytes_out) AS AvgBytesSent, stddev(bytes_out) AS StdevBytesSent BY src_ip, dst_ip, dst_port, _timeslice
| sort BY src_ip, dst_ip, dst_port, _timeslice
| stats count AS ConnectionCount, avg(AvgBytesSent) AS AvgBytesSent, avg(StdevBytesSent) AS StdevBytesSent BY src_ip, dst_ip, dst_port
| where ConnectionCount >= 20
| eval JitterCV = if(StdevBytesSent > 0 AND AvgBytesSent > 0, StdevBytesSent / AvgBytesSent, 1)
| where JitterCV <= 0.15
| sort BY JitterCV asc Sumo Logic search implementing an approximation of the beacon-jitter fingerprint against firewall session logs ingested under the network/firewall source category, using byte-size regularity (stddev/mean of bytes_out) as the primary statistical signal; pair with a scheduled search or Sumo Logic Cloud SIEM rule that additionally computes inter-session timing CV for full parity with the KQL/SPL implementations.
Data Sources
Required Tables
False Positives & Tuning
- Fixed-interval monitoring and heartbeat traffic — maintain a Sumo Logic lookup table of known legitimate destinations
- Scheduled backup/replication jobs with consistent payload sizes
Other platforms for THREAT-Beacon-JitterAnalysis
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Simulate Low-Jitter HTTPS Beacon via Scheduled curl Loop
Expected signal: Firewall/proxy or Zeek conn.log sessions from the test host to test-endpoint.example on port 443, roughly 60-66 seconds apart, with a low coefficient of variation on both interval and byte count.
- Test 2Simulate Regular-Interval Beacon via PowerShell Scheduled Loop
Expected signal: Firewall/proxy session logs showing regular ~60-66 second interval HTTPS sessions from the test host to test-endpoint.example.
- Test 3Simulate High-Jitter Traffic as Negative Control
Expected signal: Session log entries to test-endpoint.example with highly variable inter-connection intervals (5-605 seconds).
Response Playbook
Triage
- Pull the full connection history for the flagged (SourceIP, DestinationIP, DestinationPort) tuple and manually inspect the interval sequence and byte sizes — confirm the low-CV pattern holds over the full available retention window, not just the alerting window.
- Check the destination IP/domain's registration age, hosting provider, and passive DNS history — freshly registered domains, bulletproof/rotating hosting, or domains with no legitimate business relationship to the organisation are strong corroborating signals.
- Correlate the source host with endpoint telemetry (process creation, network connections) around the same time window to identify the process responsible for the beaconing traffic; absence of a corresponding endpoint agent on that host is itself notable and consistent with the network-only visibility this detection is designed to cover.
- Inspect TLS certificate details (issuer, validity period, SAN) for HTTPS beacons where certificate metadata is available in the flow log — self-signed or very recently issued certificates increase confidence.
- Compare the beacon's timing profile against known malleable C2 defaults (e.g., default Cobalt Strike sleep/jitter, common Sliver/Mythic profiles) — an exact match to a well-known default profile is high-confidence evidence, though a professional operator will typically customise these values.
Containment
- Block the destination IP/domain at the firewall or web proxy as an immediate containment step once corroborating evidence raises confidence above the false-positive baseline.
- Isolate the source host via EDR if an endpoint agent is present and the beaconing is confirmed active, particularly if paired with process-level indicators of a known C2 implant.
- For unmanaged/agentless devices (network appliances, IoT), contain at the network layer (VLAN isolation, switch port shutdown) since host-based isolation is not available.
- Capture a PCAP of ongoing sessions to the suspicious destination before blocking, to preserve evidence of the beacon's request/response structure for malware analysis.
Evidence Collection
- Full connection/session history for the flagged tuple, including exact timestamps and byte counts for every session
- PCAP or full packet capture of representative sessions, if available, to inspect the HTTP/TLS request structure
- TLS certificate chain for the destination if HTTPS, and passive DNS / WHOIS history for the destination domain
- Endpoint process and network telemetry for the source host covering the full time window, if an EDR agent is present
- Any proxy or firewall logs showing the User-Agent, URI path, and request method used in the beacon check-in
Escalation Criteria
- !Interval CV is very low (<=0.05) and sustained over a long observation window (multiple days), which is difficult to produce with anything other than an automated beacon
- !Destination domain/IP has no plausible legitimate business relationship with the organisation and shows other threat-intelligence red flags (young registration, bulletproof hosting)
- !The source host cannot be attributed to a known monitoring, backup, or SaaS-polling application after investigation
- !Beaconing is correlated with a host also showing credential-access, lateral-movement, or collection-phase indicators
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Firewall/proxy session logs or Zeek conn.log covering the full available retention window for the flagged tuple - >
PCAP of representative sessions, including TLS handshake metadata (JA3/JA3S fingerprints where captured) and, if decrypted, HTTP request/response structure - >
Endpoint process execution and network connection telemetry for the source host, where an EDR agent is present - >
Passive DNS and WHOIS history for the destination domain - >
TLS certificate details for the destination (issuer, validity period, SAN) if HTTPS
Tuning Guidance
Start by baselining the environment's legitimate fixed-interval traffic (monitoring agent heartbeats, backup/replication jobs, SaaS polling integrations) over at least a week, and build an explicit allowlist of those source/destination pairs — without it, this detection will alert heavily on benign automated traffic, since low timing variance is common to many non-malicious automated systems, not just C2 beacons. Once the allowlist is in place, treat any new, unallowlisted tuple crossing both the interval-CV and byte-size-CV thresholds as a priority investigation. Raising MinConnections reduces false positives from short-lived legitimate sessions at the cost of a longer time-to-detect; lowering MaxJitterCV increases precision at the cost of missing beacons configured with higher jitter percentages.
Hunting Queries
Hunt over 7 days for any destination IP/port receiving an unusually high session count — establishes a baseline of legitimate high-volume destinations (CDNs, SaaS APIs, internal services) to allowlist before running the jitter-CV detection, and surfaces any high-volume destination that does not fit an expected legitimate pattern for deeper investigation.
CommonSecurityLog
| where TimeGenerated > ago(7d)
| where DestinationPort in (80, 443, 8080, 8443)
| summarize ConnectionCount = count(), Devices = dcount(SourceIP) by DestinationIP, DestinationPort
| where ConnectionCount > 500
| sort by ConnectionCount desc index=network sourcetype="zeek:conn" earliest=-7d
| where id.resp_p IN (80,443,8080,8443)
| stats count AS ConnectionCount, dc(id.orig_h) AS SourceCount BY id.resp_h, id.resp_p
| where ConnectionCount > 500
| sort - ConnectionCount Atomic Red Team Tests
Runs a scripted loop that issues an HTTPS GET request to a test endpoint at a fixed interval with a small randomised jitter, simulating the timing signature of a malleable-profile C2 beacon (e.g., default-ish Cobalt Strike/Sliver sleep+jitter behaviour) for detection validation purposes.
Command
for i in $(seq 1 40); do curl -s -o /dev/null -A "Mozilla/5.0" https://test-endpoint.example/checkin; sleep $((60 + RANDOM % 6)); done Cleanup
pkill -f test-endpoint.example || true Expected Telemetry
Firewall/proxy or Zeek conn.log sessions from the test host to test-endpoint.example on port 443, roughly 60-66 seconds apart, with a low coefficient of variation on both interval and byte count.
Expected Detection
Alert fires once the (SourceIP, DestinationIP, DestinationPort) tuple accumulates >= 20 sessions with JitterCV <= 0.15 within the 24-hour lookback window.
Windows equivalent of the curl-loop simulation, using Invoke-WebRequest on a fixed interval to validate the detection against Windows-originated network flow logs.
Command
for ($i=0; $i -lt 40; $i++) { Invoke-WebRequest -Uri 'https://test-endpoint.example/checkin' -UseBasicParsing | Out-Null; Start-Sleep -Seconds (60 + (Get-Random -Minimum 0 -Maximum 6)) } Cleanup
Get-Process powershell | Where-Object { $_.MainWindowTitle -eq '' } | Stop-Process -Force -ErrorAction SilentlyContinue Expected Telemetry
Firewall/proxy session logs showing regular ~60-66 second interval HTTPS sessions from the test host to test-endpoint.example.
Expected Detection
Alert fires on the low-jitter beacon pattern once the connection count and interval-CV thresholds are met.
Issues HTTPS requests at highly irregular intervals to validate that the detection does not fire on traffic with genuinely high timing variance, exercising the false-positive boundary of the JitterCV threshold.
Command
for i in $(seq 1 40); do curl -s -o /dev/null https://test-endpoint.example/checkin; sleep $((RANDOM % 600 + 5)); done Cleanup
pkill -f test-endpoint.example || true Expected Telemetry
Session log entries to test-endpoint.example with highly variable inter-connection intervals (5-605 seconds).
Expected Detection
Detection should NOT fire for this tuple, since the resulting interval coefficient of variation should exceed the 0.15 MaxJitterCV threshold — used to validate the false-positive boundary.