Ian Beer — Project Zero iOS Exploits
Ian Beer (Google Project Zero) là một trong những iOS security researchers có ảnh hưởng nhất. Công trình của ông định hình cách community hiểu và exploit iOS kernel. Mỗi exploit đều kèm write-up chi tiết — đây là tài liệu học tốt nhất.
Tại Sao Ian Beer Quan Trọng
- Tiên phong nhiều kỹ thuật exploitation mà community dùng đến nay
- Write-ups xuất sắc — giải thích rõ ràng từng bước, tốt để học
- mach_portal (2016) và async_wake (2017) là nền tảng cho unc0ver và nhiều jailbreaks
- AWDL exploit (2020) chứng minh zero-click wormable attack qua Wi-Fi
- In-the-wild analysis (2019) phân tích 5 exploit chains thật từ targeted attacks
Exploits Theo Thời Gian
1. mach_portal (December 2016) — iOS 10.1.1
| Field | Detail |
|---|---|
| CVE | CVE-2016-7644, CVE-2016-7661, CVE-2016-7637 |
| Target | iOS 10.1.1 |
| Technique | Mach port replacement + kernel UAF |
| Result | tfp0 (kernel task port) |
Chain:
1. CVE-2016-7637: Mach port name replacement vulnerability
→ Replace port name in transit → type confusion
2. CVE-2016-7644: set_dp_control_port kernel UAF
→ Dangling port reference in kernel
3. CVE-2016-7661: Sandbox escape via powerd
→ Escape sandbox to reach kernel attack surface
Exploit flow:
Sandbox escape → trigger kernel UAF
→ Reallocate freed port with controlled data
→ Fake port pointing to kernel task
→ tfp0 achieved
Historical significance:
- Đầu tiên demonstrate Mach port UAF → fake task port technique
- Technique này trở thành standard trong iOS exploitation suốt 4 năm
- Source code published → community builds jailbreaks trên đó (Yalu)
2. async_wake (December 2017) — iOS 11.1.2
| Field | Detail |
|---|---|
| CVE | CVE-2017-13861 |
| Target | iOS 11.1.2, mọi devices |
| Component | IOSurfaceRootUserClient |
| Technique | IOSurface UAF → fake task port → tfp0 |
| Write-up | Kèm PoC local kernel debugger |
Vulnerability:
IOSurfaceRootUserClient external method
→ s_set_surface_notify — sets a notification port on an IOSurface
→ Bug: port reference count off by one
→ Port freed but still referenced → UAF
Exploitation:
1. Allocate mach port
2. Call s_set_surface_notify → kernel stores extra reference
3. Deallocate port (bug: refcount goes to 0 → freed)
4. Port memory freed but IOSurface still holds pointer
5. Heap spray: send OOL port descriptors cùng size với ipc_port
→ Freed port memory reallocated with controlled data
6. Trigger IOSurface notification → kernel uses fake port
7. Fake port configured as IKOT_TASK → points to fake task
8. Fake task's map = kernel_map
9. mach_vm_read_overwrite / mach_vm_write → kernel r/w
Key technique introduced: OOL port descriptor spray cho port replacement. Became standard pattern.
Impact trực tiếp:
- Electra jailbreak (iOS 11.0-11.1.2) built trên async_wake
- unc0ver initial versions dùng technique tương tự
- Taught community cách chain IOSurface bug → fake port → tfp0
3. In-the-Wild iOS Exploit Chains Analysis (August 2019)
| Field | Detail |
|---|---|
| Published | August 29, 2019 |
| Content | Phân tích 14 vulnerabilities trong 5 exploit chains |
| iOS range | iOS 10 → 12 |
| Source | Captured from watering hole attacks (real targets) |
5 chains phân tích:
Chain 1: iOS 10.0-10.3.3 (Exploit Chain 1)
Chain 2: iOS 10.3-10.3.3 (Exploit Chain 2)
Chain 3: iOS 11.0-11.4.1 (Exploit Chain 3)
Chain 4: iOS 12.0-12.1 (Exploit Chain 4)
Chain 5: iOS 12.0-12.1.2 (Exploit Chain 5)
Mỗi chain gồm:
WebKit exploit → Sandbox escape → Kernel exploit → Implant
Implant capabilities:
- Upload contacts, photos, GPS location
- Keychain dump (passwords, tokens)
- iMessage/WhatsApp/Telegram database
- Real-time GPS tracking
Tại sao quan trọng:
- Đầu tiên public detailed analysis of real-world iOS exploit chains
- Cho thấy mức sophistication của nation-state attackers
- 5 chains cover 2 years → attacker maintained exploits across iOS updates
- Từng vulnerability được explain với root cause + exploitation technique
- Tài liệu học hoàn hảo — real bugs, real exploitation, real impact
4. oob_timestamp (CVE-2020-3837) — Analyzed by Brandon Azad
| Field | Detail |
|---|---|
| CVE | CVE-2020-3837 |
| Target | iOS 13.3 |
| Component | XNU vm_map_copy |
| Technique | One-byte OOB write → change vm_map_copy type → physical memory mapping |
| Write-up | “One Byte to Rule Them All” (Brandon Azad, Project Zero) |
Vulnerability:
One-byte out-of-bounds write
→ Overwrites type field of vm_map_copy_t structure
→ Changes type from ENTRY_LIST (1) to KERNEL_BUFFER (2) hoặc OBJECT (3)
→ iOS is little-endian → single byte enough to change type
Exploitation:
1. Trigger one-byte OOB write
2. Overwrite vm_map_copy type field: ENTRY_LIST → KERNEL_BUFFER
3. vm_map_copy giờ interpreted as kernel buffer
→ Internal fields have different meaning under new type
→ "Size" field = previously a pointer → huge size
4. → Read past buffer boundary → kernel info leak
5. Escalate to physical memory mapping:
→ Map all of DRAM into userspace
→ Full physical read/write
Key insight: vm_map_copy is a UNION-like structure
Type 1: entries[] = linked list of VM entries
Type 2: kdata = pointer to kernel buffer + size
→ Change type = reinterpret same bytes differently = type confusion
Bài học: “One byte is enough” — dù chỉ 1 byte OOB write, nếu target đúng structure có thể escalate thành full physrw.
5. AWDL Wormable Wi-Fi Exploit (December 2020)
| Field | Detail |
|---|---|
| CVE | CVE-2020-3843 (+ thêm 2 radio proximity 0-days) |
| Target | iOS 13.x (mọi iPhones trong Wi-Fi range) |
| Component | AWDL (Apple Wireless Direct Link) protocol |
| Type | Zero-click, wormable, radio proximity |
| Write-up | “An iOS Zero-Click Radio Proximity Exploit Odyssey” |
| Development time | 6 tháng (solo) |
Attack vector:
AWDL = peer-to-peer Wi-Fi protocol (AirDrop, Sidecar, ...)
→ Always on, always listening for AWDL frames
→ No user interaction needed — just be in Wi-Fi range
→ WORMABLE: compromised device có thể attack nearby devices
Exploit setup:
Hardware: Raspberry Pi + 2 Wi-Fi adapters (~$100 total)
Vulnerability:
Buffer overflow in AWDL frame parsing:
1. Send crafted AWDL action frames via Wi-Fi
2. Target's AWDL stack parses frame → buffer overflow
3. Overflow in kernel (AWDL runs in kernel space)
→ Kernel code execution from Wi-Fi proximity
Exploitation:
1. Activate target's AWDL interface (broadcast AirDrop-like beacons)
2. Send overflow frames → kernel memory corruption
3. Heap grooming via Wi-Fi frames → controlled corruption
4. → Kernel read/write → full device compromise
Total time from first frame to compromise: ~2 minutes
Tại sao đây là exploit đáng sợ nhất:
- Zero-click: victim không cần làm gì
- No app needed: không cần victim cài app hay click link
- Radio proximity: chỉ cần ở gần (Wi-Fi range ~100m)
- Wormable: device compromised → tự attack devices khác nearby
- Kernel-level: AWDL stack chạy trong kernel → instant kernel code exec
Demo: Beer demonstrate trên iPhone 11 Pro — toàn quyền truy cập photos, email, messages, real-time monitoring.
Kỹ Thuật Chung Của Ian Beer
Fake Task Port Pattern
Được Beer popularize và refine qua nhiều exploits:
1. Trigger kernel vulnerability → get dangling/corrupted port reference
2. Heap spray OOL port descriptors → replace freed port memory
3. Fake port structure:
ip_object.io_bits = IO_BITS_ACTIVE | IKOT_TASK
kdata.task = address of fake task structure
4. Fake task structure:
map = kernel_map address
5. mach_vm_read(fake_port, kaddr, size) → reads kernel memory
6. mach_vm_write(fake_port, kaddr, data, size) → writes kernel memory
Evolved over:
mach_portal (2016) → async_wake (2017) → various (2018-2019)
Killed by:
zone_require (iOS 14) + PAC (iOS 12+ arm64e)
Write-Up Style
Beer’s write-ups follow consistent pattern — excellent for learning:
- Vulnerability discovery — how the bug was found
- Root cause — why the bug exists in code
- Exploitation strategy — how to turn bug into primitive
- Heap layout control — specific grooming technique
- Primitive construction — building kread/kwrite
- Post-exploitation — what you can do with it
Tài Nguyên — Đọc Theo Thứ Tự
- mach_portal (2016) — Start here: introduces Mach port exploitation
- async_wake (2017) — Refined IOSurface + fake port technique
- A very deep dive into iOS Exploit chains (2019) — Real-world chain analysis, 5 parts
- One Byte to Rule Them All (2020, Brandon Azad) — vm_map_copy type confusion
- AWDL Radio Proximity Exploit (2020) — Magnum opus: wormable zero-click
- A Survey of Recent iOS Kernel Exploits (2020) — Overview tổng hợp
Source Code
PoC Deep Dive: AWDL — Remote Heap Grooming Qua Wi-Fi
Vulnerability cụ thể
// parseAwdlSyncTreeTLV — parser cho AWDL Sync Tree TLV
// 2-byte length field từ untrusted TLV → controls memcpy size
// Destination buffer: 60 bytes trên kernel heap
// Max length accepted: 1024 bytes → linear heap overflow 6 bytes mỗi step
void parseAwdlSyncTreeTLV(uint8_t *tlv_data, uint16_t tlv_len) {
char dest_buf[60]; // Stack/heap buffer
uint16_t copy_len = *(uint16_t *)(tlv_data + 2); // Untrusted!
// BUG: no validation that copy_len <= sizeof(dest_buf)
memcpy(dest_buf, tlv_data + 4, copy_len); // OVERFLOW!
}
Remote Heap Spray via SRD
// Attacker machine: craft AWDL action frame with Service Response Descriptors
// Each SRD → controlled kalloc allocation on target device kernel
struct awdl_frame {
struct ieee80211_header wifi_hdr;
uint8_t awdl_header[...];
struct srd_tlv srds[N]; // Multiple SRDs per frame
};
// Mỗi SRD:
// - type = AWDL_SRD_TLV_TYPE
// - length = target_kalloc_size (2 byte, up to 64KB)
// - data = arbitrary bytes
// → Kernel allocates kalloc(length), copies data
// → Controllable size AND content = perfect heap spray
// Grooming strategy:
// 1. Spray thousands of SRDs → fill target kalloc zone
// 2. Send frames with different source MACs → create IO80211AWDLPeer objects
// 3. Control RSSI → control insertion order → control heap layout
// 4. Create holes by deauthenticating specific "peers"
// 5. Trigger overflow → corrupt adjacent IO80211AWDLPeer
Remote Kernel Read (BSS Steering Trick)
// IO80211AWDLPeer struct has fields:
// steering_msg_blob (pointer) ← adjacent to overflow buffer
// steering_msg_size (size_t) ← can be corrupted too
// After overflow corrupts these fields:
// steering_msg_blob = TARGET_KERNEL_ADDR
// steering_msg_size = READ_SIZE
// Trigger BSS steering state machine:
// → Kernel calls buildMasterIndicationTemplate()
// → Reads steering_msg_size bytes from steering_msg_blob
// → Embeds data in outbound AWDL frame
// → Attacker captures Wi-Fi frame → READS KERNEL MEMORY!
// This is kernel-to-radio information disclosure
// No need for any userspace access on victim device
PoC Deep Dive: oob_timestamp — vm_map_copy Type Confusion
Stability Trick: Breaking the Loop
// vm_map_copyout_internal() holds vm_map lock while processing entries
// If we just corrupt and leave → function won't terminate properly → panic
// Solution: "overlay" technique
// 1. Create fake vm_map_entry chain that eventually terminates
// 2. Last fake entry's vme_next = vm_map_copy header (end sentinel)
// 3. Scan kernel stack of blocked thread
// 4. Replace pointer to corrupted vm_map_copy with clean copy
// 5. Loop terminates normally → function returns → no panic
// This is why Brandon Azad's technique is stable:
// Not just "trigger bug" but carefully engineer clean exit
Physical Address → Kernel Base
// PPL blocks mapping kernelcache pages directly
// But hardware MMIO registers are NOT protected by PPL!
// AMCC (Apple Memory Controller) register at phys 0x200000680:
// RORGNBASEADDR = KTRR region physical base address
// → This IS the kernelcache physical base
volatile uint64_t *amcc_reg = map_physical(0x200000680);
uint64_t ktrr_base = *amcc_reg;
// ktrr_base = physical address of kernel __TEXT
// Now map kernel __DATA segment (not KTRR-protected):
volatile void *kernel_data = map_physical(ktrr_base + data_offset);
// → Direct read/write to kernel data structures!