Hacktricks-skills macos-thread-injection
macOS thread injection and IPC exploitation reference. Use this skill whenever the user asks about macOS security research, privilege escalation, task ports, thread hijacking, Mach IPC, process injection, EndpointSecurity detection, or Apple Silicon (arm64e) exploitation. Trigger for macOS security audits, EDR development, or understanding macOS process isolation bypasses.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port/SKILL.MDmacOS Thread Injection via Task Port
A reference guide for macOS thread injection techniques using task ports, including detection and hardening strategies.
When to Use This Skill
Use this skill when working with:
- macOS security research and privilege escalation
- Thread injection and process manipulation
- Mach IPC and task port exploitation
- EndpointSecurity event monitoring
- Apple Silicon (arm64e) exploitation considerations
- EDR/AV development for macOS
- Security audits of macOS applications
Core Concepts
Thread Hijacking
When
task_threads() is available on a task port, you can hijack existing threads rather than creating new ones (which is blocked by thread_create_running() mitigation).
Key operations on remote threads:
- halt executionthread_suspend()
- resume executionthread_resume()
/thread_get_state()
- read/modify registersthread_set_state()
Remote function call pattern:
- Set registers
-x0
to function argumentsx7 - Set
to target function addresspc - Resume thread
- Detect return (via exception handler or loop monitoring)
Return value detection strategies:
- Exception handler: Set
to invalid address, register exception port vialrthread_set_exception_ports() - Loop monitoring: Set
to infinite loop, poll registers untillr
hits loop instructionpc
Mach Port Communication
Establish bidirectional communication between local and remote tasks:
Local port setup:
// Create receive right in local task mach_port_allocate(MACH_PORT_RIGHT_RECEIVE, &local_port) // Transfer send right to remote via THREAD_KERNEL_PORT thread_set_special_port(remote_thread, THREAD_KERNEL_PORT, local_port) // Remote thread calls mach_thread_self() to retrieve send right
Remote port setup:
// Remote thread creates port via mach_reply_port() mach_port_insert_right() to establish send right thread_set_special_port() to stash in kernel // Local task retrieves via thread_get_special_port()
Memory Read/Write Primitives
Reading memory - use
property_getName() from libobjc:
const char *property_getName(objc_property_t prop) { return prop->name; // ldr x0, [x0]; ret }
Writing memory - use
_xpc_int64_set_value() from libxpc:
// Writes x1 to [x0 + 0x18] // For arbitrary 64-bit write at address: _xpc_int64_set_value(address - 0x18, value)
Shared Memory Setup
Use
OS_xpc_shmem objects for efficient data transfer:
- Allocate memory via
mach_vm_allocate() - Create
object viaOS_xpc_shmemxpc_shmem_create() - Copy template to remote process (fix Mach send right at offset 0x18)
- Insert send right via
thread_set_special_port() - Map with remote
callxpc_shmem_remote()
Full Control Capabilities
Once you have arbitrary execution + shared memory:
- Memory R/W:
between local and shared regionsmemcpy() - Multi-argument calls: Stack arguments per ARM64 calling convention
- Mach port transfer: Pass rights via established ports
- File descriptor transfer: Use fileports (see triple_fetch)
Apple Silicon (arm64e) Considerations
Pointer Authentication Codes (PAC) protect return addresses and function pointers.
Safe approaches:
- Reuse existing code (original
/lr
values have valid PAC)pc - Chain existing gadgets/functions (ROP)
For attacker-controlled memory:
// 1. Allocate executable memory in target mach_vm_allocate() + mprotect(PROT_EXEC) // 2. Copy payload // 3. Sign pointer INSIDE remote process uint64_t ptr = (uint64_t)payload; ptr = ptrauth_sign_unauthenticated((void*)ptr, ptrauth_key_asia, 0); // 4. Set pc = ptr in hijacked thread state
Detection and Hardening
EndpointSecurity Events
Monitor these events for thread injection detection:
| Event | Trigger |
|---|---|
| Task port request (e.g., ) |
| Thread created in different task |
| Register manipulation (macOS 14+) |
Swift detection client:
import EndpointSecurity let client = try! ESClient(subscriptions: [.notifyRemoteThreadCreate]) { _, msg in if let evt = msg.remoteThreadCreate { print("[ALERT] remote thread in pid \(evt.target.pid) by pid \(evt.thread.pid)") } } RunLoop.main.run()
osquery query (≥ 5.8):
SELECT target_pid, source_pid, target_path FROM es_process_events WHERE event_type = 'REMOTE_THREAD_CREATE';
Hardening Recommendations
- Remove
entitlement - prevents non-root task port accesscom.apple.security.get-task-allow - Enable Hardened Runtime - adds additional protections
- Monitor EndpointSecurity events - detect injection attempts
- Code signing - verify integrity of loaded code
- SIP awareness - System Integrity Protection blocks many Apple binaries
Tooling Reference
| Tool | Year | Purpose |
|---|---|---|
| threadexec | 2018 | Thread injection library |
| task_vaccine | 2023 | PAC-aware thread hijacking PoC |
| 2024 | EndpointSecurity helper for EDR vendors |
Key References
Important Notes
- macOS 13/14+: API changes affect compatibility - review recent tooling source code
- Intel vs Apple Silicon: Different exploitation paths due to PAC on arm64e
- Legal: Only use on systems you own or have explicit authorization to test
- Defensive focus: Understanding these techniques helps build better EDR and hardening