What Is an NDR?
HuntRule Team · · 10 min read

On this page
An ESXi host, a badge controller and a load balancer have one thing in common. No EDR agent runs on any of them, and none of them will ever accept one. Network detection and response is the tooling that watches those hosts anyway, by reading the traffic they send instead of the code they run.
NDR is a sensor plus an analytics layer plus some response hooks. The sensor sees a copy of traffic, decodes protocols and writes records. The analytics layer runs rules and baselines over those records. Response is usually an integration that blocks at a firewall or quarantines through the EDR, not an action the sensor takes itself. The category was called network traffic analysis before the rename. The rename added response. It did not change the data.
The argument for it is inventory arithmetic. Count your EDR seats, then count DHCP leases on the same subnets. The second number is always larger. Printers, cameras, hypervisor management interfaces, appliances and contractor laptops all live in that gap.
Three kinds of network telemetry
What you can hunt is decided by which of these you collect.
Source | Record | Storage at 1 Gbps sustained | Answers |
|---|---|---|---|
Flow (NetFlow v9, IPFIX, sFlow, VPC flow logs) | 5-tuple, byte and packet counts, start and end, TCP flags | Megabytes per day | Who talked to whom, how much, how often |
Protocol metadata (Zeek, Suricata EVE, Corelight) | Per-protocol logs: | Single-digit gigabytes per day | Which domain, which cipher, which SMB path, which certificate |
Full packet capture | Every byte on the wire | 10.8 TB per day | Everything, including payloads you can reassemble |
The pcap figure is arithmetic. 1 Gbps is 125 MB/s, and 125 MB/s across 86400 seconds is 10.8 TB. Most teams keep 24 to 72 hours of rolling capture for incident use and hunt on metadata for everything else.
Flow is the cheapest and the weakest. sFlow is sampled, commonly 1 in 2000 packets, so a beacon sending 400 bytes every 60 seconds may never produce a record. NetFlow and IPFIX are unsampled on most enterprise gear, but a flow record still cannot tell you which hostname was requested or which TLS library made the request.
Protocol metadata is where hunting happens. A Zeek conn.log row carries duration, orig_bytes, resp_bytes, conn_state and history, and joins to every other log through uid. A JSON conn.log line is a few hundred bytes, so ten million connections a day is single-digit gigabytes.
What survives TLS
Encryption removes payload, not behaviour.
The client's TLS ClientHello is cleartext. JA3, published by Salesforce in 2017, is an MD5 hash over the TLS version, cipher list, extension list, elliptic curves and curve point formats. Its weakness is ordering. Chromium randomised its extension order in 2023, and cipher stunting randomises the cipher order, which shatters one client into thousands of JA3 values.
JA4 sorts the ciphers and extensions before hashing, and stays human readable:
t13d1516h2_8daaf6152771_e5627efa2ab1Read left to right: t is TLS over TCP, 13 is TLS 1.3, d means an SNI was present, 15 is the cipher count ignoring GREASE, 16 is the extension count, h2 is the first and last character of the first ALPN value. The two hashes are truncated SHA-256 over the sorted cipher list and over the sorted extension list plus signature algorithms. Because the format is a_b_c, you can hunt on a and c alone and ignore b, which is how you track an actor who rotates a single cipher to break exact matching. JA4S covers the server response, JA4X certificates, JA4SSH sessions. The ServerHello stays cleartext in TLS 1.3, so server fingerprints survive.
Past fingerprints you keep SNI in ssl.log server_name, session duration, byte counts per direction and inter-arrival timing. That is enough for beaconing, long connection and volumetric exfiltration analysis, none of which need a plaintext byte.
Now the honest part. TLS 1.3 encrypts the server Certificate message, so the issuer, subject and SAN fields that used to land in x509.log are gone for 1.3 sessions. Self-signed certificate hunting quietly stopped working on the modern half of your traffic. Encrypted Client Hello removes server_name too, wherever it is deployed. You also lose HTTP URIs, user agents, request bodies and file extraction, which means no hashes off the wire for anything moved over HTTPS. Anyone selling full visibility into encrypted traffic without a decryption proxy is selling metadata under another name.

Placement decides what you see
A sensor sees the traffic that reaches it and nothing else. Four decisions set that boundary.
North-south versus east-west. A perimeter sensor sees egress and inbound. It never sees SMB from one workstation to another, so lateral movement (
T1021.002) is invisible to it. East-west coverage means sensors per segment, and traffic between two VMs on the same hypervisor may never touch a physical wire.SPAN versus TAP. A SPAN port is a switch feature and is oversubscribable. Mirror two 10 Gbps links into one 10 Gbps SPAN port and the switch drops the excess silently, usually the packets you needed. A TAP is a passive split of the physical link, cannot be oversubscribed by configuration, and fails open.
Inline versus passive. Inline gives you blocking and makes the sensor a failure domain on that link. Passive gives you detection only and cannot break production.
Direction. Asymmetric routing that sends one direction past the sensor and the other around it breaks protocol parsing outright. Zeek logs a half connection with
conn_stateofS0orOTHand noservice, and the TLS logs go empty.
NAT is the other trap. A sensor outside a NAT boundary collapses every internal host into one source IP. Put sensors inside the boundary, or accept that every hit needs a DHCP or firewall log join to name a machine.
Cloud is a different product with different gaps. AWS Traffic Mirroring copies from an elastic network interface and delivers VXLAN-encapsulated packets to another ENI, a Network Load Balancer or a Gateway Load Balancer endpoint, and AWS notes you may see out-of-order delivery through the load balancer targets. Google Cloud Packet Mirroring sends copies to collectors behind an internal load balancer. Both share one structural hole. No ENI or VM NIC you control means no mirror session, which rules out most managed and serverless services. Flow logs are the fallback, and they give you the 5-tuple, not the handshake.
Worked hunt: periodic sessions with no jitter
Beaconing is the detection that only network telemetry answers well. A callback on a timer produces inter-arrival gaps with almost no variance. The measurement is the coefficient of variation: standard deviation of the gaps over their mean.
This runs against Zeek conn.log rows in Postgres, with ts as epoch seconds the way Zeek writes it and dotted field names flattened to underscores.
WITH gaps AS (
SELECT
id_orig_h,
id_resp_h,
id_resp_p,
ts - LAG(ts) OVER (
PARTITION BY id_orig_h, id_resp_h, id_resp_p
ORDER BY ts
) AS gap
FROM conn
WHERE ts >= EXTRACT(EPOCH FROM NOW()) - 86400
AND proto = 'tcp'
),
scored AS (
SELECT
id_orig_h,
id_resp_h,
id_resp_p,
COUNT(*) AS sessions,
AVG(gap) AS mean_gap,
STDDEV_POP(gap) AS sd_gap
FROM gaps
WHERE gap IS NOT NULL
GROUP BY 1, 2, 3
)
SELECT
id_orig_h,
id_resp_h,
id_resp_p,
sessions,
ROUND(mean_gap::numeric, 1) AS mean_gap_seconds,
ROUND((sd_gap / NULLIF(mean_gap, 0))::numeric, 3) AS jitter_ratio
FROM scored
WHERE sessions >= 24
AND mean_gap BETWEEN 30 AND 3600
AND sd_gap / NULLIF(mean_gap, 0) < 0.05
ORDER BY jitter_ratio ASC, sessions DESC;It catches any client-initiated TCP session that repeats on a fixed timer at least 24 times in a day with under 5 percent relative jitter, regardless of TLS, port or destination reputation. Map it to T1071.001 and T1029.
The false positives are the majority of your results. Update checks, monitoring agents, RMM tools, certificate revocation checks, NTP and telemetry uploaders all beacon perfectly. Build a first-seen allowlist keyed on id_resp_h and destination port from a week of output, then review it rather than trust it.
The blind spots matter more. An operator who sets 30 percent jitter pushes the ratio well past 0.05 and walks through this query. Raising the threshold to 0.35 catches them and multiplies the noise, so run that as a separate lower-priority hunt. A beacon holding one long-lived TCP session produces no repeat connections at all, so hunt those on conn.log duration instead. And a beacon reaching its C2 through the corporate proxy shows one destination, the proxy, which collapses the grouping.
A second pass on the same data uses fingerprint rarity. Count distinct clients per JA4 across a server subnet and read the tail:
SELECT
ja4,
COUNT(*) AS connections,
COUNT(DISTINCT id_orig_h) AS clients,
MIN(ts) AS first_seen
FROM ssl
WHERE ts >= EXTRACT(EPOCH FROM NOW()) - 2592000
AND id_orig_h << inet '10.20.0.0/16'
GROUP BY ja4
HAVING COUNT(DISTINCT id_orig_h) <= 2
ORDER BY connections DESC;Two caveats. Base Zeek populates neither ja4 nor ja3, both come from packages you load. And FoxIO states that JA4 values change as TLS libraries are updated, roughly once a year, so a patch wave produces a burst of benign new rare fingerprints. The real blind spot is malware using the host's own TLS stack, WinHTTP or Schannel on Windows, which inherits a very common fingerprint and never reaches the tail.
Where NDR fails and EDR does not
NDR cannot see what never crosses a monitored boundary. In-memory execution, local privilege escalation, credential access from LSASS, registry persistence and file encryption on a local disk produce no packets. It cannot read payloads under TLS. Behind a proxy or NAT it struggles to name a host.
EDR fails in the complementary places. It is absent on unmanageable hosts by definition. It can be unhooked, killed or blinded by an attacker with SYSTEM, and when it stops reporting, so does your visibility. It sees nothing on the network device the attacker pivots from.
That is the whole argument. When an agent goes silent, its host keeps generating packets and the sensor keeps writing records the attacker cannot reach. When a sensor sees only encrypted bytes, the agent on that host sees the process that sent them. You buy both because the failure modes do not overlap. If you are building the content that sits on top of either, detection engineering is the discipline that turns this telemetry into rules you can maintain.
Summary
NDR earns its budget on coverage, not cleverness. It watches hosts no agent will ever run on, and that set is always larger than the asset inventory claims. Collect protocol metadata over flow if you can afford one thing, because flow cannot answer which domain or which fingerprint. Encryption removes payload and, under TLS 1.3, certificate detail as well, but leaves timing, volume and handshake fingerprints intact. Expect cloud coverage to be partial no matter what you buy.
Collect at minimum (Zeek log: fields)
conn.log: ts, uid, id.orig_h, id.resp_h, id.resp_p, proto, service,
duration, orig_bytes, resp_bytes, conn_state, history
ssl.log: ts, uid, version, cipher, server_name, next_protocol,
established, validation_status, ja3, ja4 (packages required)
dns.log: ts, uid, query, qtype_name, rcode_name, answers
x509.log: certificate.subject, certificate.issuer, san.dns (TLS 1.2 only)
http.log: ts, uid, host, uri, user_agent, method (cleartext only)
ATT&CK coverage of the hunts above
T1071.001 Application Layer Protocol: Web Protocols
T1573.002 Encrypted Channel: Asymmetric Cryptography
T1029 Scheduled Transfer
T1090 Proxy
T1571 Non-Standard Port
T1021.002 Remote Services: SMB/Windows Admin SharesNetwork rules in the catalog live at /rules?domain=network. Start with the beaconing and TLS fingerprint rules, tune the allowlist against a week of your own traffic, then promote them.
Related articles

What Is Event Correlation in SIEM?
Windows Security event 4625 on its own is a typo. Thirty of them against thirty different account names from one source address in fifteen minutes, followed by a 4624 from that same address, is a…
2026-04-0610 min read

What Is Log Normalization in SIEMs?
Sysmon calls it Image. Windows Security event 4688 calls it NewProcessName. Microsoft Defender for Endpoint splits the same thing into FolderPath and FileName. All three describe one executable…
2026-02-268 min read

What Is SOAR?
POST /devices/entities/devices-actions/v2?action_name=contain takes a CrowdStrike host off the network. action_name=lift_containment puts it back. Both are one HTTP call against the same endpoint,…
2025-08-1810 min read