← All cheat sheets

MACOS FORENSICS

Plain-text reference · 11 KB. Read it, search it (Ctrl-F) or print it.

Defensive / DFIR quick reference for macOS (Intel and Apple Silicon).
Blue-team only: what to collect, where artifacts live, how to triage.
Collect in order of volatility; work on a copy, hash everything. Many
of these files are gated by Full Disk Access (TCC) - grant Terminal
FDA, or read them from a mounted image. Paths shown for recent macOS
(Monterey 12 - Tahoe 26); some move between versions (untested on 26).

ORDER OF VOLATILITY#

1. Memory (RAM) - hardest on Apple Silicon; grab first if feasible
2. Running processes, open files, network state
3. System/user caches, unified log ring buffer
4. Disk: filesystem, databases, plists, logs
5. Backups (Time Machine), external/archival media

LIVE TRIAGE: SYSTEM + PROCESSES#

sw_vers                              # product name, version, build
system_profiler SPSoftwareDataType   # OS, uptime, boot mode, SIP note
uname -a ; hostname                  # kernel / host
csrutil status                       # System Integrity Protection on/off
sysctl hw.model machdep.cpu.brand_string  # hardware / CPU (Intel vs ARM)
date -u ; uptime
ps auxwww                            # all processes, args
ps -axo pid,ppid,user,lstart,command # with start time + parent
lsof -nP                             # open files (needs root for all)
lsof -i -nP                          # network-connected processes

USERS + LOGIN HISTORY#

dscl . -list /Users UniqueID | awk '$2>=500'  # real users (UID>=500)
dscl . -list /Users                  # ALL accounts incl _service ones
dscl . -read /Users/<user>           # one account (UID, home, shell)
dscl . -read /Groups/admin GroupMembership   # who is an admin
# dslocal plists (offline on an image):
#   /var/db/dslocal/nodes/Default/users/<user>.plist
last                                 # login history (utmpx records)
who ; w                              # current sessions
log show --predicate 'process == "loginwindow"' --last 7d  # GUI logins
# FileVault-unlock + console logins also show in the unified log.

UNIFIED LOG (primary macOS log store)#

# Live stream + historical query (binary .tracev3, not text files):
log stream --info --predicate 'eventMessage CONTAINS "fail"'
log show --last 1h --info --debug    # recent, incl info/debug events
log show --predicate 'process == "sudo"' --last 1d
log show --predicate 'subsystem == "com.apple.securityd"' --last 1d
# Collect the whole store for offline analysis:
log collect --output /evidence/logs.logarchive
log show /evidence/logs.logarchive --predicate '...'
# On-disk store (parse offline with mac_apt / UnifiedLogReader):
#   /var/db/diagnostics/   (+ /var/db/uuidtext/ for string lookups)
# Note: default store is only days of history - collect early.

PERSISTENCE#

# Launchd jobs (plists). Check Contents, ProgramArguments, RunAtLoad:
~/Library/LaunchAgents/              # per-user agents
/Library/LaunchAgents/               # all users, agents
/Library/LaunchDaemons/              # system daemons (run as root)
# Apple's own (SIP-protected, normally trusted):
/System/Library/Launch{Agents,Daemons}/
launchctl list                       # loaded jobs (scope = who runs it;
                                     #   root -> system, user -> that GUI)
launchctl print gui/$(id -u)         # detailed per-user domain
launchctl print system               # system domain
# Login / background items (Ventura 13+ Background Task Mgmt):
sfltool dumpbtm                      # all BTM login + launchd items
#   store: /private/var/db/com.apple.backgroundtaskmanagement/
#   (BackgroundItems-v*.btm, a binary plist; dumpbtm decodes it)
# Managed configuration profiles (MDM or rogue):
sudo profiles list                   # installed profiles (run as root)
#   /Library/Managed Preferences/ , /var/db/ConfigurationProfiles/
# Login/logout hooks (legacy but still honoured):
defaults read com.apple.loginwindow LoginHook LogoutHook 2>/dev/null
# Shell startup files (per user + system):
cat ~/.zshrc ~/.zprofile /etc/zshrc /etc/zprofile 2>/dev/null
# System extensions / kexts:
systemextensionsctl list ; kextstat -l
# Older / legacy mechanisms:
crontab -l                           # per-user cron (/usr/lib/cron/tabs/)
ls -la /etc/periodic/ /etc/periodic/*/   # periodic scripts
ls -l /etc/rc.common /etc/rc.local 2>/dev/null  # rc.local not run by launchd
ls -la /Library/StartupItems/ 2>/dev/null       # deprecated startup items
# emond was removed in Ventura; /etc/emond.d/ only on older systems.

GATEKEEPER / QUARANTINE / XPROTECT#

spctl --status                       # Gatekeeper assessment on/off
spctl -a -vvv /path/to/App.app       # assess a bundle's signature
xattr -l <file>                      # show com.apple.quarantine + source
# Quarantine events (download provenance) - SQLite LSQuarantineEvent
# table; cols LSQuarantineTimeStamp (Mac absolute time, secs since
# 2001-01-01), LSQuarantineAgentName, LSQuarantineDataURLString,
# LSQuarantineOriginURLString. Per user:
~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2
# XProtect (Gatekeeper yara data) + XProtect Remediator (XProtect.app):
/Library/Apple/System/Library/CoreServices/XProtect.bundle   # signatures
/Library/Apple/System/Library/CoreServices/XProtect.app      # Remediator
# Sequoia 15.2+: active bundle copy also at /var/protected/xprotect/.
system_profiler SPInstallHistoryDataType   # XProtect/MRT version history
codesign -dvvv --entitlements :- /path/App.app  # signature + entitlements

TCC (privacy permissions - who got mic/camera/FDA/etc)#

# SQLite 'access' table cols: service, client, client_type (0=bundle
# id, 1=absolute path), auth_value, last_modified (Unix epoch).
~/Library/Application Support/com.apple.TCC/TCC.db   # per-user grants
/Library/Application Support/com.apple.TCC/TCC.db    # system grants
# Read needs Full Disk Access (TCC), or read it from a mounted image.
# auth_value: 0=denied 1=unknown 2=allowed 3=limited (newer schema).
# kTCCServiceSystemPolicyAllFiles = Full Disk Access.

SPOTLIGHT + FSEVENTS (file activity)#

mdls <file>                          # all Spotlight metadata of a file
mdls -name kMDItemWhereFroms <file>  # download source URL(s)
mdfind -onlyin /path "query"         # search the Spotlight index
# FSEvents (dir-level change log) - parse offline (FSEventsParser).
# Catalina+ the data lives on the Data volume:
/System/Volumes/Data/.fseventsd/     # (/.fseventsd via firmlink on live)
# Spotlight store (offline): /System/Volumes/Data/.Spotlight-V100/

ACTIVITY DATABASES (user behaviour timeline)#

# knowledgeC - app usage, focus, device lock/unlock (parse w/ APOLLO):
~/Library/Application Support/Knowledge/knowledgeC.db       # per-user
/private/var/db/CoreDuet/Knowledge/knowledgeC.db           # system
# macOS 13+ (Ventura): much of this activity moved to the Biome store
#   ~/Library/Biome/  and  /private/var/db/biome/ - check both.
# Power log (process/app activity, APOLLO-parseable) - a .PLSQL SQLite
# DB; its exact path varies by version, so locate it on the image:
sudo find /private/var -iname '*powerlog*' 2>/dev/null
# Recent / opened items (SharedFileList, binary plists):
~/Library/Application Support/com.apple.sharedfilelist/

USER + BROWSER ARTIFACTS#

cat ~/.zsh_history ~/.bash_history 2>/dev/null   # shell history
ls -la@ ~/Downloads                  # -@ shows xattrs (quarantine)
# Safari (SQLite / plist):
~/Library/Safari/History.db
~/Library/Safari/Downloads.plist
# Chrome / Edge (SQLite): .../Google/Chrome/Default/History
# Mail, Messages (chat.db), Notes live under ~/Library/ too.
plutil -p <file>.plist               # pretty-print any (binary) plist
defaults read <domain>               # read a preference domain

INSTALL + SYSTEM HISTORY#

# Package install receipts (what was installed, when, by whom):
/Library/Receipts/InstallHistory.plist
ls -la /var/db/receipts/             # .bom + .plist per installed pkg
pkgutil --pkgs                       # installed package IDs
system_profiler SPApplicationsDataType  # installed apps + signed-by

NETWORK STATE#

lsof -i -nP                          # sockets with owning process
netstat -anv                         # all connections (BSD netstat)
nettop -P -l 1                       # per-process traffic snapshot
arp -an                              # ARP cache
scutil --dns                         # resolver config
networksetup -listallnetworkservices # configured services
ifconfig -a
# Config state (offline on image):
#   /Library/Preferences/SystemConfiguration/

KEYCHAIN + AUDIT#

security list-keychains              # keychain search list
#   ~/Library/Keychains/login.keychain-db  (user secrets - needs pwd)
#   /Library/Keychains/System.keychain
# OpenBSM audit trail (if auditing enabled; deprecated but present):
ls -la /var/audit/                   # binary audit logs (BSM)
praudit -l /var/audit/<trailfile>    # decode one trail, one line/record
cat /etc/security/audit_control      # audit policy / flags

ACQUISITION (APFS, FileVault)#

diskutil list                        # volumes / APFS containers
diskutil apfs list                   # APFS detail (encryption state)
fdesetup status                      # FileVault on? (need key to decrypt)
# T2 + Apple Silicon encrypt internal storage in hardware, so a raw dd
# of the PHYSICAL disk yields ciphertext. Image the UNLOCKED synthesized
# APFS data volume device instead (find it in `diskutil list`), e.g.:
dd if=/dev/rdisk3s1 of=/evidence/disk.raw bs=4m conv=noerror,sync
shasum -a 256 /evidence/disk.raw | tee /evidence/disk.raw.sha256
# hdiutil makes a COMPRESSED logical image (not bit-for-bit) of a volume:
hdiutil create -srcdevice /dev/diskXsY -format UDZO /evidence/img
# Live triage / logical collection (preferred on modern Macs):
#   mac_apt (-> SQLite), a Velociraptor agent, or `sysdiagnose`.
# RAM: no public tool on Apple Silicon; osxpmem is legacy (kext, <= 10.x).

TIMELINE + TOOLS#

# Build a super-timeline from a triage image or live host:
#   mac_apt         - artifact parser -> SQLite/CSV (many of the above)
#   APOLLO          - knowledgeC / powerlog pattern-of-life timeline
#   FSEventsParser  - .fseventsd into readable events
#   log show --style json  - unified log slices into your timeline
# File times incl. APFS birth time (%SB) via BSD stat:
stat -f '%N B=%SB m=%Sm c=%Sc a=%Sa' <file>   # birth/mod/change/access

REFERENCES#

# Apple Platform Security guide (SIP, Gatekeeper, FileVault, keychain)
# Apple man pages: log(1), spctl(8), fs_usage(1), launchctl(1)
# SANS FOR518 macOS/iOS Forensic Analysis
# mac_apt: github.com/ydkhatri/mac_apt
# APOLLO: github.com/mac4n6/APOLLO
# FSEventsParser: github.com/dlcowen/FSEventsParser
# MITRE ATT&CK macOS: T1543.001/.004 (launchd agent/daemon),
#   T1547.015 (login items), T1553.001 (Gatekeeper bypass),
#   T1555.001 (keychain)

Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.