Collecting Forensic Evidence on macOS
A practical guide to gathering volatile and persistent forensic data from macOS systems for security investigations
Forensic evidence collection on macOS follows a fundamental principle: collect the most volatile data first. Memory contents disappear the instant a machine powers off, running processes vanish when they terminate, and network connections close without warning. Persistent data on disk, by contrast, survives a reboot. This guide walks Mac administrators through a structured evidence collection process, from the most fleeting artifacts to the most durable.
The Order of Volatility
Collect evidence in this order – the top of the list disappears fastest:
| Priority | Data Type | Volatility |
|---|---|---|
| 1 | System memory (RAM) | Lost on power-off |
| 2 | Running processes | Lost on termination |
| 3 | Network connections | Lost on disconnect |
| 4 | Logged-in users / sessions | Lost on logout |
| 5 | Loaded kernel extensions | Lost on reboot |
| 6 | Temporary files (/tmp, /var/tmp) | May be cleared on reboot |
| 7 | System logs (Unified Log) | Rotated over time |
| 8 | BSM audit logs | Rotated per policy |
| 9 | User data and application logs | Persistent |
| 10 | Disk image | Persistent |
Volatile Data Collection
Collect these items while the Mac is still running. Work quickly but methodically, and record the exact UTC time you begin.
Running Processes
# Full process listing with user, PID, CPU, memory, and command
ps aux > /Volumes/Evidence/processes_$(date -u +%Y%m%dT%H%M%SZ).txt
# Process tree view showing parent-child relationships
pstree -u > /Volumes/Evidence/pstree_$(date -u +%Y%m%dT%H%M%SZ).txt 2>/dev/null
Look for processes running from unusual locations (/tmp, /var/tmp, user home directories), processes with high CPU or memory usage, and processes owned by unexpected users.
Network Connections
# All network connections with process names and PIDs
lsof -i -P -n > /Volumes/Evidence/lsof_network_$(date -u +%Y%m%dT%H%M%SZ).txt
# Established connections only
netstat -an | grep ESTABLISHED > /Volumes/Evidence/netstat_$(date -u +%Y%m%dT%H%M%SZ).txt
# DNS cache (may reveal recently resolved malicious domains)
sudo dscacheutil -cachedump -entries Host 2>/dev/null > /Volumes/Evidence/dns_cache_$(date -u +%Y%m%dT%H%M%SZ).txt
Open Files
# All open files on the system
sudo lsof > /Volumes/Evidence/lsof_all_$(date -u +%Y%m%dT%H%M%SZ).txt
Loaded Kernel Extensions
# List loaded kexts (fewer on modern macOS with System Extensions)
kextstat > /Volumes/Evidence/kextstat_$(date -u +%Y%m%dT%H%M%SZ).txt
Logged-In Users and Sessions
# Currently logged-in users
who > /Volumes/Evidence/who_$(date -u +%Y%m%dT%H%M%SZ).txt
# Recent login history
last -20 > /Volumes/Evidence/last_$(date -u +%Y%m%dT%H%M%SZ).txt
# Current user sessions
w > /Volumes/Evidence/w_$(date -u +%Y%m%dT%H%M%SZ).txt
System Memory
Memory acquisition on modern macOS (especially Apple Silicon) is challenging due to System Integrity Protection and the Secure Enclave. Options include:
- Commercial tools such as Recon for Mac (Sumuri) or MacQuisition (BlackBag / Cellebrite) that use signed kernel extensions or DFU-based acquisition.
- Virtual machines – If the Mac is a VM, take a snapshot, which includes a memory dump.
- Process-specific dumps – If you cannot acquire full memory, dump individual suspect processes using
lldborsample.
# Sample a suspect process for 10 seconds
sudo sample <PID> 10 -file /Volumes/Evidence/sample_pid_$(date -u +%Y%m%dT%H%M%SZ).txt
Persistent Data Collection
Once volatile data is secured, collect the durable artifacts.
Unified Logs
The macOS Unified Logging system is the richest source of persistent forensic data. Export a broad time range surrounding the suspected compromise.
# Export the last 24 hours of logs to a .logarchive file
sudo log collect --last 24h --output /Volumes/Evidence/unified_logs.logarchive
# Export specific subsystem logs (e.g., security events)
log show --predicate 'subsystem == "com.apple.securityd"' --last 24h \
> /Volumes/Evidence/securityd_$(date -u +%Y%m%dT%H%M%SZ).txt
Tip: The
.logarchiveformat preserves the full log database and can be opened later withlog showor Console.app for analysis. Always preferlog collectoverlog showfor evidence preservation.
BSM Audit Logs
If OpenBSM auditing is enabled, these logs record system calls, authentication events, and file access.
# Copy the audit log directory
sudo cp -R /var/audit /Volumes/Evidence/bsm_audit/
# Read audit logs with praudit
sudo praudit /var/audit/current > /Volumes/Evidence/audit_current_$(date -u +%Y%m%dT%H%M%SZ).txt
LaunchDaemons and LaunchAgents
Malware commonly persists through LaunchDaemons and LaunchAgents. Collect all of them for analysis.
# System-level persistence
sudo ls -la /Library/LaunchDaemons/ > /Volumes/Evidence/sys_launchdaemons.txt
sudo cp -R /Library/LaunchDaemons/ /Volumes/Evidence/LaunchDaemons_System/
sudo ls -la /Library/LaunchAgents/ > /Volumes/Evidence/sys_launchagents.txt
sudo cp -R /Library/LaunchAgents/ /Volumes/Evidence/LaunchAgents_System/
# User-level persistence (for each user)
ls -la ~/Library/LaunchAgents/ > /Volumes/Evidence/user_launchagents.txt
cp -R ~/Library/LaunchAgents/ /Volumes/Evidence/LaunchAgents_User/
# Apple system daemons (for reference)
ls -la /System/Library/LaunchDaemons/ > /Volumes/Evidence/apple_launchdaemons.txt
Scheduled Jobs
# Cron jobs for all users
for user in $(dscl . list /Users | grep -v '^_'); do
echo "=== $user ===" >> /Volumes/Evidence/crontabs.txt
sudo crontab -u "$user" -l >> /Volumes/Evidence/crontabs.txt 2>&1
done
# At jobs
sudo atq > /Volumes/Evidence/atjobs.txt 2>&1
Crash Reports and Diagnostic Data
# System crash reports
sudo cp -R /Library/Logs/DiagnosticReports/ /Volumes/Evidence/DiagnosticReports_System/
# User crash reports
cp -R ~/Library/Logs/DiagnosticReports/ /Volumes/Evidence/DiagnosticReports_User/
Browser History and Downloads
Browser artifacts often reveal the initial infection vector (phishing link, drive-by download).
# Safari history database
cp ~/Library/Safari/History.db /Volumes/Evidence/safari_history.db
# Safari downloads plist
cp ~/Library/Safari/Downloads.plist /Volumes/Evidence/safari_downloads.plist
# Chrome history (if installed)
cp ~/Library/Application\ Support/Google/Chrome/Default/History \
/Volumes/Evidence/chrome_history.db 2>/dev/null
The sysdiagnose Command
Apple’s sysdiagnose tool collects a comprehensive system snapshot in a single command. It gathers log data, system configuration, network state, and more.
# Generate a full sysdiagnose (may take several minutes)
sudo sysdiagnose -f /Volumes/Evidence/
Note:
sysdiagnoseproduces a large.tar.gzarchive and can take 5-10 minutes to complete. It collects Unified Logs, network configuration, I/O Kit state, system profiler data, and more. It is an excellent single-command evidence package.
Disk Imaging
For a full forensic investigation, create a bit-for-bit image of the disk.
Intel Macs
Boot from an external macOS Recovery or forensic boot drive, then image the internal disk:
# Create a raw disk image using dd
sudo dd if=/dev/disk0 of=/Volumes/Evidence/disk_image.raw bs=4096 conv=noerror,sync
# Or create a compressed DMG using hdiutil
sudo hdiutil create -srcdevice /dev/disk0 -format UDZO \
/Volumes/Evidence/disk_image.dmg
Apple Silicon Macs
Apple Silicon Macs do not support Target Disk Mode in the traditional sense. Instead:
- DFU mode – Place the Mac in DFU mode and use Apple Configurator 2 or a commercial forensic tool (Cellebrite, GrayKey) for acquisition.
- Share Disk mode (macOS Recovery) – Boot to Recovery, use
diskutilto mount the volume, and image it from another Mac connected via USB-C. - Live imaging – If DFU is not an option, image the disk from the running system (less forensically sound but sometimes necessary).
# Live disk image (running system -- last resort)
sudo dd if=/dev/disk0 of=/Volumes/Evidence/disk_image.raw bs=4096
Important: FileVault-encrypted volumes must be unlocked before imaging. If the Mac is running and the user is logged in, the volume is already decrypted in memory. If the Mac is off, you will need the FileVault recovery key from your MDM.
Hashing Evidence
Hash every evidence file immediately after collection to prove integrity later.
# Generate SHA-256 hashes for all evidence files
find /Volumes/Evidence -type f -exec shasum -a 256 {} \; \
> /Volumes/Evidence/evidence_hashes.sha256
Verify hashes at the start of any analysis session to confirm nothing has been altered.
Chain of Custody Log
Maintain a written record for every piece of evidence. Use this template:
| Field | Value |
|---|---|
| Evidence ID | (unique identifier) |
| Description | (what was collected) |
| Source Device | (hostname, serial number) |
| Collected By | (name, title) |
| Collection Date/Time | (UTC) |
| Collection Method | (command, tool) |
| SHA-256 Hash | (hash value) |
| Storage Location | (path or physical location) |
| Transfer History | (who handled it, when, why) |
Recommended Tools
| Tool | Purpose | Source |
|---|---|---|
| osquery | Fleet-wide endpoint state queries | osquery.io |
| KnockKnock | Enumerate persistent software | Objective-See |
| BlockBlock | Monitor persistence event creation | Objective-See |
| TaskExplorer | Inspect running tasks and dylibs | Objective-See |
| Santa | Binary allow/deny-listing and logging | Google (github.com/google/santa) |
| AutoMacTC | Automated macOS forensic triage | CrowdStrike (github.com/CrowdStrike/automactc) |
| mac_apt | macOS Artifact Parsing Tool | github.com/ydkhatri/mac_apt |
| sysdiagnose | Built-in comprehensive system snapshot | Apple (pre-installed) |
Next Steps
- Understand isolation procedures: Isolating a Compromised Mac
- Follow the full response workflow: Mac Admin Incident Response Checklist
- Learn about macOS audit logging: BSM Audit Logs