BIPI
BIPI

macOS Endpoint Forensics: Unified Logs, FSEvents, and the TCC Database

Cybersecurity

Triage on a Mac is not Windows with different folder names. UAC for macOS, Unified Logs, FSEvents, KnowledgeC.db, TCC privacy permissions, LaunchAgents persistence, and the Apple silicon considerations that change collection.

By Arjun Raghavan, Security & Systems Lead, BIPI · July 12, 2024 · 8 min read

#macos#dfir#forensics

macOS forensics in 2024 is its own discipline. The artifact set is different from Windows in ways that surprise teams who treat it as a port of NTFS-era tradecraft. The Unified Logging System replaced syslog years ago, FSEvents records every file change but in a journal format you have to decode, and the entire privacy permission model lives in a SQLite database that doubles as a behavioural signal goldmine.

Triage collection: UAC for macOS

UAC (Unix-like Artifacts Collector) is the open-source equivalent of KAPE for Unix systems and has a macOS profile that covers the essential artifact set. Run it with sudo, get an output archive, ship it off the box. The artifacts include Unified Logs, FSEvents, LaunchAgents, LaunchDaemons, the TCC database, browser histories, quarantine database, and shell histories. Do not try to do this with cp and find; the permission model on modern macOS will refuse you in ways you only discover when you need the file.

For Apple silicon Macs, full disk imaging is materially different from Intel. The boot volume is sealed and signed (SSV), and the data volume is APFS encrypted by default. You will not be making a bit-for-bit image of a running Apple silicon Mac without secrets that the user must consent to release. Live triage with UAC is usually what you actually want anyway.

Unified Logs: the firehose that is also the answer

log show and log collect are how you read and capture the Unified Log system. The catch is that it is a firehose; an hour of macOS activity is gigabytes of log entries. Use predicates to filter (log show --predicate 'subsystem == "com.apple.SecurityServer"' --info), and use log collect with a tight time window to grab a manageable archive. The information density is enormous: every code-signing check, every keychain access, every launchd start, every screen lock state change.

Critical investigative subsystems to know: com.apple.securityd (code signing and key access), com.apple.tccd (privacy permission decisions), com.apple.launchd (process launches), com.apple.network (connection events), com.apple.kernel (everything system-call adjacent). Get fluent in predicate syntax; it pays back fast.

FSEvents and KnowledgeC.db

FSEvents is the per-volume change journal at /.fseventsd. It records what changed and roughly when, in a compact binary format. The fsevents-parser and mac_apt projects can decode it. The journal is more granular than people expect and survives across reboots; it is often the only record of a file that the attacker created and then deleted.

KnowledgeC.db, under /private/var/db/CoreDuet/Knowledge/, is the activity database that Spotlight, Siri, and Apple Intelligence use to learn user patterns. From a forensic angle, it tracks app usage, focus state, screen-on time, and Bluetooth proximity events. For insider cases and user-attribution questions, it is gold. The mac_apt and APOLLO projects parse it.

TCC.db: the privacy permission goldmine

TCC (Transparency, Consent, and Control) is macOS's per-app permission database. It lives at /Library/Application Support/com.apple.TCC/TCC.db (system-wide) and ~/Library/Application Support/com.apple.TCC/TCC.db (per-user). Every time an app gets permission to access the camera, microphone, full disk, location, contacts, or accessibility, an entry is written. For investigations, the question is always which apps requested or were granted access to sensitive data, and when. Accessibility permission in particular is a high-signal find because attackers abuse it for keylogging and UI automation.

Persistence: LaunchAgents and LaunchDaemons

The plist-based persistence locations are well known but worth restating: /Library/LaunchAgents (system-wide, per-user run), /Library/LaunchDaemons (system-wide, root run), ~/Library/LaunchAgents (per-user, user run), and /System/Library/LaunchDaemons (Apple, do not touch). Any unsigned plist in the first three is a finding. Codesign every binary referenced by every plist; an attacker frequently drops a binary at a path that mimics a real Apple service name but has no valid signature.

Login items are the modern adjunct: managed via SMAppService since macOS 13, they show up in /Library/LaunchAgents and the equivalent user-managed location, but System Settings exposes them under Login Items. The system_profiler SPDeveloperToolsDataType output and sfltool dumpbtm are how you enumerate them programmatically.

Signed-binary abuse and Live-off-the-Land

macOS has its own LOLBins. osascript for AppleScript-driven persistence, sqlite3 for direct database manipulation, plutil for plist abuse, and the curl-piped-to-bash dropper pattern. Apple's notarisation requirement raised the bar on unsigned malware but did not eliminate it; many attackers now use signed-but-malicious binaries from compromised developer certificates. Track which developer ID signed each persistent binary you find, and cross-reference against Apple's revoked developer ID list and the Objective-See lookup tools.

Apple silicon: what changes

Apple silicon introduces System Integrity Protection variants, the Secure Enclave, and a different boot security model. For triage, the practical impacts are: live memory acquisition is harder (vmware-vdiskmanager-style tricks do not apply), kernel extensions are largely replaced by system extensions running in userland, and certain forensic tools written for Intel will not run natively. Plan for live triage as the default and full imaging as the exception, and budget for the licensing and time of macOS-specific commercial forensics if your caseload justifies it.

Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.