MacSecLabs
0.5Free preview
DE 00 · Module 0.5 · Beginner

File System, Process, Network, and Identity Telemetry

An event describes an action at a moment in time. State describes what remains when you look. Detection engineers need both. If a file-write event was missed, a new LaunchAgent plist may still exist. If a process event was retained but the process exited, a later ps query cannot reconstruct it.

This module checks four kinds of state on your macOS 27 VM: files, processes, listening sockets, and local group membership. Each snapshot has a clear limit.

Decide whether the question needs an event or a snapshot

Before choosing a command, write the question in time. "Is a LaunchAgent present now?" is a state question. "Who created it yesterday?" is an event-history question. A present-day directory listing cannot answer the second. The same distinction applies to a running process versus a past execution, an open socket versus a completed flow, and today's group membership versus the change that granted it.

QuestionUseful state viewHistorical source requiredCommon mistake
Which persistence file exists?Plist, owner, mode, signature of referenced programRetained file event or installer/MDM record for the writerTreating modification time as definitive creation time
Which process runs now?ps, lsof, signature of the executableRetained execution event for ancestry and argumentsJoining two records on PID without time or boot context
Which service listens now?netstat and current socket ownerFlow, firewall, proxy, or packet record for past trafficCalling a listener an outbound connection
Who is locally privileged now?Directory group and authorization stateAccount-management and authorization historyTreating group membership as evidence that a privileged action occurred

The collection contract must name the source, capture cadence, retention, required privileges, and fields actually exported by the deployed product. An ES client can observe many process and file operations, but only if it subscribes and preserves them. A point-in-time command can corroborate an event but cannot retroactively restore a missed one. A system log may explain a decision but may not identify the initiating process well enough to join the case. Document these limits before promising coverage.

Files: ask what changed and who can explain it

A persistence file is useful evidence when you can establish its path, content, owner, timestamps, and creation context. A path alone is weak. A legitimate installer may create a LaunchAgent; a user shell may do the same. Compare the job label, ProgramArguments, file permissions, and signing identity of the referenced executable.

Common places to inspect include:

Path or artifactQuestion
~/Library/LaunchAgentsWhich jobs run in this user's session?
/Library/LaunchDaemonsWhich jobs can start as system services?
Application and system extensionsWhich signed provider was installed or activated?
~/Library/Application SupportWhich app owns the data and how is it used?
Temporary directoriesIs this a short-lived build product or staged material?

The com.apple.quarantine extended attribute can help establish download provenance. Many creation and transfer paths never add it. To investigate removal, find an earlier capture of the attribute or an event showing its change. Other extended attributes have their own provenance limits.

FSEvents can support historical file-system reconstruction, but it is not a complete per-file activity log. A directory change record does not identify every writer or establish file contents. DE 12 covers artifact preservation and corroboration.

Processes: a snapshot has no memory

launchd process identity
% ps -p 1 -o pid=,ppid=,comm=
    1     0 /sbin/launchd

The command confirms that launchd is PID 1 on this VM. It does not show every process launch since boot. A running process can be inspected with ps and lsof; historical ancestry requires retained execution events or another trustworthy timeline.

When a process is still running, collect its PID, executable path, parent, responsible process where available, signing identity, start time, and open resources. PIDs can be reused. Join records with time and stronger identity fields instead of treating a PID as a durable key.

A "word processor spawned a shell" rule is useful only if the sensor's parent field refers to the intended parent. macOS can report a direct parent and a responsible process that answer different questions. DE 01 teaches that distinction using real ES records.

Network: socket state is not flow history

TCP listening sockets
% netstat -an -p tcp | awk '$6=="LISTEN" && $4=="*.22" {print $1,$4,$6}'
tcp4 *.22 LISTEN
tcp6 *.22 LISTEN

This snapshot shows an SSH listener on IPv4 and IPv6 wildcard addresses. Test reachability from the relevant network segment; host firewall rules, network segmentation, and cloud or router controls still matter. Use process attribution and retained flow records to identify the owner and earlier connections.

For process attribution, inspect the owning socket with lsof while it exists. For connection history, use a configured Network Extension provider, firewall logs, proxy records, DNS logs, or packet capture. Endpoint Security's Unix-domain socket events are not a general TCP flow feed. Correlate a DNS query with connection records before reporting a connection. A flow record carries connection metadata, while payload inspection requires a different source.

The built-in packet filter can log selected traffic when configured to do so. Do not assume /var/log/pf.log exists or that every Mac retains DNS queries from mDNSResponder. Validate the actual source before naming it in a detection.

Identity: membership is a baseline, not a change event

local admin membership
% dscl . -read /Groups/admin GroupMembership
GroupMembership: root _mbsetupuser tester01

The lab user appears in the local admin group. That does not mean the user is currently running as root. It also cannot tell you when the membership was added. To detect a change, compare a prior baseline or collect the relevant administrative action and authentication events. Directory-backed identities and managed groups may need separate directory or MDM evidence.

For an escalation case, distinguish these facts:

  1. The account belongs to an administrative group.
  2. A process requested elevation.
  3. An authorization decision allowed it.
  4. A process or file operation ran with elevated authority.

Skipping directly from the first fact to the fourth produces a false claim. DE 07 builds identity and authorization detections from the full chain.

Reconstruct one case across sources

Suppose a new LaunchDaemon plist appears and a previously unknown binary listens on a port. The file and socket snapshots justify a hunt. They do not yet establish a malicious installation. Collect:

  • The plist content, owner, permissions, and timestamps.
  • The referenced executable's path, signature, and hash.
  • The process identity and socket owner while the process runs.
  • The installer's or writer's process event, if retained.
  • Management records showing whether an approved package deployed it.

Compare this with a normal installer on the same device class. A rule can then target the distinguishing chain, such as an unexpected writer creating a system job that points to a user-writable binary followed by a new listener.

Detection engineering

State is a useful second view of activity, with different timing limits from event streams. Report what a snapshot establishes, collect earlier events when available, and use a benign deployment as the comparison before turning the finding into an alert.

What Comes Next

Module 0.6 measures the quality of that evidence: whether a rule matches controlled behavior, how it behaves on benign activity, and which missing fields constrain confidence.

Continue macOS Detection Engineering

These foundation modules are open as a preview. Full modules, lab downloads, progress tracking, and certificate workflow require active course access.

Get full access