Cross-Cutting Attack Patterns Analysis
This document analyzes cross-cutting patterns used throughout exploits by Ian Beer, Siguza, Brandon Azad, and threat actors (Operation Triangulation, Coruna, DarkSword). Each pattern includes PoC pseudocode from actual exploit source code.
Pattern 1: Mach Port UAF β Fake Port β tfp0
Used by: v0rtex (Siguza), async_wake (Ian Beer), mach_portal (Ian Beer), SockPuppet, voucher_swap
The most common pattern in iOS exploitation (iOS 10-13). Later mitigated by zone_require (iOS 14), but still fundamental knowledge.
General Flow
1. Trigger vulnerability β mach port reference count decremented one too many
2. Port freed but userland still has a handle
3. Spray controlled data into the freed port memory
4. Use dangling handle β access fake port
5. Fake port configured as IKOT_TASK β points to fake task
6. fake task β map = kernel_map
7. mach_vm_read/write via fake port = kernel read/write
Pattern 2: Heap Spray & Grooming Techniques
Used by: Every kernel exploit
OOL Mach Message Spray
// Standard heap spray: send OOL messages to fill a kalloc zone
void spray_kalloc(uint32_t size, void *data, int count, mach_port_t *ports) {
for (int i = 0; i < count; i++) {
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &ports[i]);
struct {
mach_msg_header_t hdr;
mach_msg_body_t body;
mach_msg_ool_descriptor_t ool;
} msg = {};
msg.hdr.msgh_bits = MACH_MSGH_BITS_COMPLEX |
MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg.hdr.msgh_size = sizeof(msg);
msg.hdr.msgh_remote_port = ports[i];
msg.body.msgh_descriptor_count = 1;
msg.ool.address = data;
msg.ool.size = size;
msg.ool.type = MACH_MSG_OOL_DESCRIPTOR;
msg.ool.deallocate = FALSE;
msg.ool.copy = MACH_MSG_VIRTUAL_COPY;
mach_msg(&msg.hdr, MACH_SEND_MSG, sizeof(msg), 0, 0, 0, 0);
}
}
Pattern 3: vm_map_copy Type Confusion (One Byte)
Used by: oob_timestamp (Brandon Azad), derivatives
Especially elegant: 1-byte OOB write β full physical memory access.
// vm_map_copy is a union structure β the type field determines interpretation
// Little-endian: byte 0 of type field = 0x01 (ENTRY_LIST) or 0x03 (KERNEL_BUFFER)
// β 1 byte overflow changing 0x03 β 0x01 = type confusion!
Pattern 4: Physical UAF (PUAF) Techniques
Used by: kfd (felix-pb), Dopamine, Trigon, Coruna
Modern pattern replacing the fake port technique on iOS 15+.
VM bug β physical page freed but virtual mapping retained
β Kernel reallocates physical page for another object
β Userspace still reads/writes via old virtual mapping
β If page becomes a page table β full physrw
Pattern 5: IOKit Race Condition Exploitation
Used by: IOHIDeous (Siguza), many IOKit CVEs, DarkSword
// Pattern: external method + clientClose race
// Thread 1: call external method (accesses internal object)
// Thread 2: call clientClose (frees internal object)
// β UAF if method accesses object after close frees it
Pattern 6: Parser Disagreement (Logic Bug)
Used by: psychicpaper (Siguza)
Parser behavior for <!---><!--> sequence:
CoreFoundation (amfid):
β Returns EMPTY dict (no entitlements seen)
β amfid says: "binary has no entitlements" β ALLOW
IOKit (kernel), XPC (sandbox):
β Returns dict WITH private entitlements
β Kernel/sandbox grants: no-sandbox, tfp, platform binary
Pattern 7: Radio/Remote Exploitation (AWDL)
Used by: Ian Beer AWDL exploit
AWDL Service Response Descriptors (SRDs) as remote heap spray β each SRD in an AWDL frame creates a kalloc allocation in the target deviceβs kernel, with controllable size and content.
Pattern 8: Coprocessor DMA Bypass (SPTM)
Used by: Coruna (Rocket exploit)
SPTM protects CPU memory access but DOES NOT protect DMA:
Normal CPU access:
CPU β MMU β SPTM check β Physical memory
β SPTM blocks unauthorized access
Coprocessor DMA:
GFX coprocessor β IOMMU β Physical memory
β IOMMU configuration has gaps β bypass SPTM!
Attack Pattern Matrix
| Pattern | When to use | iOS range | Complexity | Reliability |
|---|---|---|---|---|
| Fake port β tfp0 | Have port UAF | <= iOS 13 | Medium | High |
| IOSurface kread/kwrite | Have heap corruption + IOSurface | iOS 11+ | Medium | High |
| vm_map_copy type confusion | Have 1-byte OOB write | iOS 13 | High | High |
| PUAF β physrw | Have VM bug | iOS 14-16 | High | Medium-High |
| Parser disagreement | Have parser inconsistency | Any (logic bug) | Low | 100% (deterministic) |
| Race condition | Have concurrent access bug | Any | Low-Medium | Low (probabilistic) |
| OOL msg spray | Heap grooming | Any | Low | High |
| Coprocessor DMA | SPTM bypass needed | iOS 17+ | Very High | Unknown |
| Radio proximity | Remote/0-click needed | iOS 13 | Very High | Medium |
Evolution Timeline
2016: mach_portal β Fake port pattern established
2017: async_wake β IOSurface + OOL port spray refined
2017: v0rtex β OSUnserializeXML spray, multi-offset port
2017: IOHIDeous β IOKit race condition patterns
2019: SockPuppet β Socket UAF variant
2020: oob_timestamp β vm_map_copy type confusion, physrw without fake port
2020: psychicpaper β Pure logic bug, no memory corruption
2020: AWDL β Remote kernel exploitation via Wi-Fi
2022: kfd β PUAF techniques (smith, landa, physpuppet)
2023: Op. Triangulation β Hardware MMIO PPL bypass
2025: Trigon β Deterministic exploitation
2025: Coruna β Coprocessor DMA SPTM bypass
2026: DarkSword β Multi-hop sandbox escape, VFS race β physrw