THREAT-Beacon-JitterAnalysis IBM QRadar · QRadar

Detect Statistical Beacon Jitter Analysis for C2 Detection via Network Flow Logs in IBM QRadar

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

QRadar Detection Query

IBM QRadar (QRadar)
sql
SELECT
    DATEFORMAT(starttime, 'YYYY-MM-dd HH:mm:ss') AS EventTime,
    sourceip AS SourceIP,
    destinationip AS DestinationIP,
    destinationport AS DestinationPort,
    bytesreceived AS BytesReceived,
    bytessent AS BytesSent
FROM events
WHERE LOGSOURCETYPENAME(logsourceid) IN ('PaloAlto', 'Fortinet FortiGate Security Gateway', 'Cisco ASA', 'Generic Firewall')
  AND destinationport IN (80, 443, 8080, 8443)
  AND starttime > NOW() - 86400000
ORDER BY sourceip, destinationip, destinationport, starttime
LIMIT 5000
high severity medium confidence

QRadar AQL query surfacing per-session firewall records (source IP, destination IP/port, byte counts) for the common C2 ports over a 24-hour window. This is a first-pass extraction intended to feed a follow-on QRadar custom rule or external analytics pipeline that groups by (sourceip, destinationip, destinationport), reconstructs inter-session intervals, and computes the interval/byte-size coefficient of variation used by the other platform variants of this detection, since native AQL does not support the ordered-array timestamp-diff logic required to compute jitter CV inline.

Data Sources

IBM QRadar SIEMFirewall/NGFW log sources (Palo Alto, Fortinet, Cisco ASA)

Required Tables

events

False Positives & Tuning

  • Fixed-interval monitoring/heartbeat traffic — populate a QRadar reference set of known legitimate destination IPs and exclude matching sessions
  • Scheduled backup and SaaS polling traffic with a regular cadence

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.

  1. 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.

  2. 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.

  3. 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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

  1. 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.
  2. 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.
  3. For unmanaged/agentless devices (network appliances, IoT), contain at the network layer (VLAN isolation, switch port shutdown) since host-based isolation is not available.
  4. 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

  1. Full connection/session history for the flagged tuple, including exact timestamps and byte counts for every session
  2. PCAP or full packet capture of representative sessions, if available, to inspect the HTTP/TLS request structure
  3. TLS certificate chain for the destination if HTTPS, and passive DNS / WHOIS history for the destination domain
  4. Endpoint process and network telemetry for the source host covering the full time window, if an EDR agent is present
  5. 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.

Hunting — KQL
kql
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
Hunting — SPL
spl
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

Test 1 Simulate Low-Jitter HTTPS Beacon via Scheduled curl Loop
linux

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

bash
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

bash
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.

Test 2 Simulate Regular-Interval Beacon via PowerShell Scheduled Loop
windows

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

powershell
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

powershell
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.

Test 3 Simulate High-Jitter Traffic as Negative Control
linux

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

bash
for i in $(seq 1 40); do curl -s -o /dev/null https://test-endpoint.example/checkin; sleep $((RANDOM % 600 + 5)); done

Cleanup

bash
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.

Related Detections