This paper is a technical case study, not an empirical measurement study. Our methodology is therefore organized around the evidence we use and the inferential framework we apply to it, rather than around an experimental protocol.
Case Selection Criteria
We selected the CVE-2025-55177 + CVE-2025-43300 chain as the primary case using four inclusion criteria:
Real-world exploitation, confirmed by inclusion in the CISA KEV catalog [cisakev2025] and by contemporaneous reporting on civil-society victims.
Public primary documentation sufficient to reconstruct the chain without privileged access: vendor advisories, NVD entries, patch diffs, and at least one independent reverse-engineering report.
C-class memory corruption at exploitation, so that the case speaks directly to the research question.
Zero-click end-to-end, with no user action required between message receipt and code execution.
FORCEDENTRY (CVE-2021-30860) also satisfies all four criteria and is used as a historical comparison point (Section Section (forcedentry)) rather than as a second primary case. Isolated CVEs that require tap-to-open interaction, browser navigation, or installation of an attacker-controlled application were excluded, because their threat model differs qualitatively from the zero-click class studied here.
Analysis Framework
Each CVE is dissected along three axes. The root cause is the specific source-level condition—call site, allocation, missing check—that makes the bug possible. For CVE-2025-43300, this is the SamplesPerPixel vs. SOF3 component-count mismatch in Apple’s CDNGLosslessJpegUnpacker, reconstructed by Quarkslab from patch diffing of iOS 18.6.2 and macOS Sequoia 15.6.1 [quarkslab2025]. The patch is the vendor-supplied fix, treated as evidence of root cause: which check was added, which path was restricted, which validation was strengthened. Patch diffs are the most reliable external ground truth available to analysts without vendor access. Position in the chain locates the bug end-to-end: delivery primitive (CVE-2025-55177 grants reachability without interaction), exploitation primitive (CVE-2025-43300 turns reachability into remote code execution), or a glue step connecting the two.
The three-axis framework is applied symmetrically to both CVEs in Section Section (casestudy) and to FORCEDENTRY in Section Section (forcedentry), enabling a like-for-like comparison across four years and two independent ecosystems.
Pedagogical Bridge: Phoenix heap-two
To make the exploitation mechanics legible to readers without prior heap-exploit experience, we conduct a full end-to-end walkthrough of the heap-two exercise from the Exploit Education Phoenix VM. The exercise is chosen for three reasons:
Its vulnerability class is CWE-787—the same class as CVE-2025-43300.
The primitive it grants—overwrite of a function pointer adjacent on the heap—is the closest textbook analogue of what the ImageIO bug ultimately yields.
It is small enough ( 50 lines of C) for the entire heap state to be inspected in
gdbwithout losing the thread.
Setup: Installing and building heap-two.
The Exploit Education Phoenix VM is freely available from exploit.education. The heap-two source code resides in /opt/phoenix/heap-two/heap-two.c. We build the binary with:
gcc -o heap-two heap-two.c
By default, the educational binary is compiled without modern protections. We verify the mitigation state using checksec:
$ checksec --file=heap-two
Expected output: ASLR disabled, NX disabled, stack canary disabled, PIE disabled. This pedagogically useful configuration makes addresses deterministic and overflow mechanics observable without randomization obscuring the analysis.
Program structure and vulnerability.
The heap-two binary allocates two heap chunks and prompts for user input. The first chunk is a char buffer; the second is a struct containing a function pointer. A call to strcpy copies user input into the first buffer without bounds checking. Input longer than the allocated size causes overflow, corrupting the function pointer in the second chunk with an attacker-chosen value. Listing Listing (heap2) shows the essential pattern.
#define DATA_SZ 64
struct item { char data[DATA_SZ]; };
struct handler { void (*fp)(void); };
struct item *A = malloc(sizeof *A);
struct handler *B = malloc(sizeof *B);
B->fp = &safe_function; /* legitimate default */
/* Unchecked: if strlen(input) > DATA_SZ, bytes
overflow from A->data into B->fp */
strcpy(A->data, user_input);
B->fp(); /* attacker controls this call target */
Execution workflow: gdb session.
We run the binary under gdb to observe heap layout and exploitation step-by-step:
Start the binary:
gdb ./heap-twoSet breakpoint before vulnerable
strcpyContinue to breakpoint:
runInspect heap state before overflow:
x/20x &chunk1Identify the function pointer location
Step through
strcpy:niRe-examine memory after overflow
Observe the overwritten function pointer
Heap layout and the overflow.
Figure Figure (heap before) shows the heap before overflow: two malloc calls produce chunks A (user buffer, 64 bytes) and B (struct with function pointer). When strcpy copies attacker input without bounds checking, bytes beyond chunk A’s boundary overwrite chunk B’s function pointer. Figure Figure (heap after) shows the heap after overflow, with chunk B’s pointer rewritten to the address of a winner() function.
0xdeadbeef). The red arrow shows the overflow path.Exploitation: crafting the payload.
The attacker constructs a payload filling chunk A with padding, then encodes the winner() function address in little-endian format to overwrite the pointer in chunk B. The program crashes at the attacker-chosen address—a successful exploit.
Connection to CVE-2025-43300.
The structural parallel is exact: both grant controllable heap write that overwrites an adjacent function pointer. Figures in Section Section (casestudy) present (i) a side-by-side diagram aligning heap-two’s layout with the ImageIO layout reconstructed from Quarkslab’s analysis [quarkslab2025]; and (ii) screenshots of a gdb session showing the overwritten function pointer at the moment of control-flow transfer.
Tools and Primary Sources
All materials used in this study are publicly available; a summary is given in Table Table (tools). No proprietary data, no non-public code, and no new reverse engineering of Apple or WhatsApp binaries is produced or relied upon. The paper’s analytical contribution is in synthesis and pedagogical framing, not primary discovery.
| Tool / source | Role |
|---|---|
gdb |
Heap and register inspection |
checksec |
Mitigation-state verification |
| Phoenix VM | Environment for heap-two |
| Hack The Box (Pwn track) | Supplementary heap/stack exploitation practice |
| Quarkslab report [quarkslab2025] | CVE-2025-43300 root cause |
| Apple, WhatsApp advisories | Canonical CVE descriptions |
| NVD entries | CWE class, CVSS, affected versions |
| CISA KEV [cisakev2025] | Exploitation confirmation |