macOS investigations

Investigate a Mac: query the unified log with predicates, read the TCC privacy database, find LaunchAgents and LaunchDaemons, trace downloads through the quarantine xattr and Gatekeeper, use FSEvents for file history, and recognise how macOS stealers and backdoors behave.

🔒 PROLesson·16 min read·Intermediate → Advanced
macOS forensicsunified logTCCLaunchAgentsGatekeepermacOS malware

01The unified log

✓What you will learn
  • Query the unified log with log show predicates and collect a .logarchive
  • Read the TCC database to see which apps were granted privacy permissions
  • Find LaunchAgents, LaunchDaemons and Background Task Management entries
  • Trace a download through the quarantine xattr, Gatekeeper and FSEvents, and spot stealer behaviour

Since macOS 10.12 almost every subsystem logs to the unified log, a binary, compressed store in /var/db/diagnostics (tracev3 files) with format strings held in /var/db/uuidtext. You cannot grep it. You query it with the log command, filtering on structured fields with a predicate (a filter expression in Apple's NSPredicate syntax).

log collect and log showbash
# Preserve first: collect an archive to external media (needs root)
sudo log collect --last 3d --output /Volumes/IR/mbp-kp.logarchive

# Then query the archive, not the live system
log show /Volumes/IR/mbp-kp.logarchive --style syslog \
  --start "2026-11-13 02:00:00" --end "2026-11-13 03:30:00" \
  --predicate 'process == "osascript" OR process == "curl" OR subsystem == "com.apple.TCC"'

# Gatekeeper and XProtect decisions on first launch
log show --last 1d --predicate 'process == "syspolicyd" OR process == "XProtect"' --info

# Interactive authentication prompts and sudo
log show --last 1d --predicate 'process == "sudo" OR eventMessage CONTAINS[c] "authentication"'
Predicate fieldExampleUse
processprocess == "sshd"Events from one binary by name
subsystemsubsystem == "com.apple.TCC"Apple's reverse-DNS component name, the cleanest filter
categorycategory == "access"Narrows within a subsystem
eventMessageeventMessage CONTAINS[c] "quarantine"Free-text match, [c] for case-insensitive; slow, use last
processImagePathprocessImagePath BEGINSWITH "/Users/"Binaries running from user-writable paths
senderImagePathsenderImagePath CONTAINS "Security"Which library emitted the line
!Redaction and retention

Many dynamic values are logged as <private> unless a private-data profile was installed before the event; you cannot un-redact afterwards. Default and error levels persist, info and debug mostly do not unless you pass --info --debug on a configured system. Retention is size based, often days to a few weeks on a busy laptop, so collect early.

This is an advanced module

Investigations beyond Windows is part of the Pro pass. 4 more sections — the deep dives, the final design, follow-ups and the test — unlock with it.

Already a cyart.io or studio.cyart.io member? Your pass code is in your Studio account.