| name | macos-thread-injection |
| description | 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. |
macOS 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:
thread_suspend() - halt execution
thread_resume() - resume execution
thread_get_state() / thread_set_state() - read/modify registers
Remote function call pattern:
- Set registers
x0-x7 to function arguments
- Set
pc to target function address
- Resume thread
- Detect return (via exception handler or loop monitoring)
Return value detection strategies:
- Exception handler: Set
lr to invalid address, register exception port via thread_set_exception_ports()
- Loop monitoring: Set
lr to infinite loop, poll registers until pc hits loop instruction
Mach Port Communication
Establish bidirectional communication between local and remote tasks:
Local port setup:
mach_port_allocate(MACH_PORT_RIGHT_RECEIVE, &local_port)
thread_set_special_port(remote_thread, THREAD_KERNEL_PORT, local_port)
Remote port setup:
mach_port_insert_right() to establish send right
thread_set_special_port() to stash in kernel
Memory Read/Write Primitives
Reading memory - use property_getName() from libobjc:
const char *property_getName(objc_property_t prop) {
return prop->name;
}
Writing memory - use _xpc_int64_set_value() from libxpc:
_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
OS_xpc_shmem object via xpc_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
xpc_shmem_remote() call
Full Control Capabilities
Once you have arbitrary execution + shared memory:
- Memory R/W:
memcpy() between local and shared regions
- 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/pc values have valid PAC)
- Chain existing gadgets/functions (ROP)
For attacker-controlled memory:
mach_vm_allocate() + mprotect(PROT_EXEC)
uint64_t ptr = (uint64_t)payload;
ptr = ptrauth_sign_unauthenticated((void*)ptr, ptrauth_key_asia, 0);
Detection and Hardening
EndpointSecurity Events
Monitor these events for thread injection detection:
| Event | Trigger |
|---|
ES_EVENT_TYPE_AUTH_GET_TASK | Task port request (e.g., task_for_pid()) |
ES_EVENT_TYPE_NOTIFY_REMOTE_THREAD_CREATE | Thread created in different task |
ES_EVENT_TYPE_NOTIFY_THREAD_SET_STATE | 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
com.apple.security.get-task-allow entitlement - prevents non-root task port access
- 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 |
remote_thread_es | 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