Introduction
On March 4, 2026, Google and iVerify published reports about a highly sophisticated exploit kit targeting Apple iPhone devices. According to Google, the exploit kit was first discovered in targeted attacks conducted by a customer of an unnamed surveillance vendor. It was later used by other attackers in watering-hole attacks in Ukraine and in financially motivated attacks in China. Additionally, researchers discovered an instance with the debug version of the exploit kit, which revealed the internal names of the exploits and the framework name used by its developers — Coruna. Analysis of the kit showed that it relies on the exploitation of many previously patched vulnerabilities and also includes exploits for CVE-2023-32434 and CVE-2023-38606. These two vulnerabilities particularly caught our attention because they had been first discovered as zero-days used in Operation Triangulation.
Operation Triangulation is a complex mobile APT campaign targeting iOS devices. We discovered it while monitoring the network traffic of our own corporate Wi-Fi network. We noticed suspicious activity that originated from several iOS-based phones. Following the investigation, we learned that this campaign employed a sophisticated spyware implant and multiple zero-day exploits. The investigation lasted for over six months, during which we disclosed our findings in connection to the attack. Kaspersky GReAT experts also presented these findings at the 37th Chaos Communication Congress (37C3).
Although all the details of both CVE-2023-32434 and CVE-2023-38606 have long been publicly available, and other researchers have developed their own exploits without ever seeing the Triangulation code, we decided to closely investigate the exploits used in Coruna. Some of the exploit kit distribution links provided by Google remained active at the time the report was published, which allowed us to collect, decrypt, and analyze all components of Coruna.
During our analysis, we discovered that the kernel exploit for CVE-2023-32434 and CVE-2023-38606 vulnerabilities used in Coruna, in fact, is an updated version of the same exploit that had been used in Operation Triangulation. The images below illustrate a high-level overview of the two attack chains. The exploit in question is highlighted with a red rectangle.
Attack chain of Operation Triangulation (simplified)

Attack chain of Coruna (simplified)
Moreover, we discovered that Coruna includes four additional kernel exploits that we had not seen used in Operation Triangulation, two of which were developed after the discovery of Operation Triangulation. All of these exploits are built on the same kernel exploitation framework and share common code. Code similarities from kernel exploits can also be found in other components of Coruna. These findings led us to conclude that this exploit kit was not patchworked but rather designed with a unified approach. We assume that it’s an updated version of the same exploitation framework that was used — at least to some extent — in Operation Triangulation.
Technical details
While we continue to investigate all exploits and vulnerabilities used by Coruna, this post provides a high-level overview of the exploit kit and attack chain.
Safari
Exploitation begins with a stager that fingerprints the browser and selects and executes appropriate remote code execution (RCE) and pointer authentication code (PAC) exploits depending on the browser version. It also contains a URL to an encrypted file with information about all available packages containing exploits and other components. The stager also includes a 256-bit key used to decrypt it. The URL and decryption key are passed to a payload embedded in PAC exploits.
Payload
The payload is responsible for initiating the exploitation of the kernel. After initialization, the payload first downloads a file with information about other available components. To extract it, the payload performs several steps processing multiple file formats.
First, the downloaded file is decrypted using the ChaCha20 stream cipher. Decryption yields a container with the magic number 0xBEDF00D, which stores LZMA-compressed data.
The file format used by the exploit kit to store compressed data
| Offset | Field |
| 0x00 | Magic number (0xBEDF00D) |
| 0x04 | Decompressed data size |
| 0x08 | LZMA-compressed data |
The decompressed data presents another container with the magic number 0xF00DBEEF. This file format is used in the exploit kit to store and retrieve files by their IDs.
The file format used by the exploit kit to store files
| Offset | Field |
| 0x00 | Magic number (0xF00DBEEF) |
| 0x04 | Number of entries |
| 0x08 | Entry[0].File ID |
| 0x0C | Entry[0].Status |
| 0x10 | Entry[0].File offset |
| 0x14 | Entry[0].File size |
We provide a description of all possible File ID values below. At this stage, when the payload gathers information about all available file packages, this container holds only one file, and its File ID is 0x70000.
Finally, we get to the file with information about all available file packages. It starts with the magic value 0x12345678. The exploit kit uses this file format to obtain URLs and decryption keys for additional components that need to be downloaded.
The file format used by the exploit kit to store information about file packages
| Offset | Field |
| 0x00 | Magic number (0x12345678) |
| 0x04 | Flags |
| 0x08 | Directory path |
| 0x108 | Number of entries |
| 0x10C | Entry[0].Package ID |
| 0x110 | Entry[0].ChaCha20 key |
| 0x130 | Entry[0].File name |
The components required for exploiting a targeted device are selected using the Package ID. Its high byte specifies the package type and required hardware. We’ve seen the following package types:
- 0xF2 – exploit for ARM64,
- 0xF3 – exploit for ARM64E,
- 0xA2 – Mach-O loader for ARM64,
- 0xA3 – Mach-O loader for ARM64E,
- 2 – implant for ARM64,
- 0xE2 – implant for ARM64E.
The payload code also supports additional package types, such as 0xF1, an exploit for older ARM devices that do not support 64-bit architecture. Interestingly, however, the files for such exploits are missing.
Other bytes of the Package ID define the supported firmware version and CPU generation.
Some of the observed Package IDs (those with unique content)
| Package ID | Description |
| 0xF3300000 | Kernel exploit (iOS < 14.0 beta 7) and other components |
| 0xF3400000 | Kernel exploit (iOS < 14.7) and other components |
| 0xF3700000 | Kernel exploit (iOS < 16.5 beta 4) and other components |
| 0xF3800000 | Kernel exploit (iOS < 16.6 beta 5) and other components |
| 0xF3900000 | Kernel exploit (iOS < 17.2) and other components |
| 0xA3030000 | Mach-O loader (iOS 16.X) (A13 – A16) |
| 0xA3050000 | Mach-O loader (iOS 16.0 – 16.4) |
The files inside these packages are also stored in encrypted and compressed 0xF00DBEEF containers, but this time compression is optional and is determined by the second bit in the Flags field. Different packages contain different sets of files. A description of all possible File IDs is given in the table below.
Observed File IDs
| File ID | Description |
| 0x10000 | Implant |
| 0x50000 | Mach-O loader (default) |
| 0x70000 | List of additional components |
| 0x70005 | Launcher config |
| 0x80000 | Launcher in 0xF2/0xF3 packages, or Mach-O loader in 0xA2/0xA3 |
| 0x90000 | Kernel exploit |
| 0x90001 | Kernel exploit (for Mach-O loader) |
| 0xA0000 | Logs cleaner |
| 0xA0001 | Mach-O loader component |
| 0xA0002 | Mach-O loader component |
| 0xF0000 | RPC stager |
After downloading the necessary components, the payload begins executing kernel exploits, Mach-O loaders, and the malware launcher. The payload selects an appropriate Mach-O loader based on the firmware version, CPU, and presence of the iokit-open-service permission.
Kernel exploits
We analyzed all five kernel exploits from the kit and discovered that one of them is an updated version of the same exploit we discovered in Operation Triangulation. There are many small changes, but the most noticeable are as follows:
- The code takes into account more values from XNU version strings, allowing for more accurate version checking.
- Added a check for iOS 17.2. We assume that this was the latest version of iOS at the time of development (released in December 2023).
- Added checks for newer Apple processors: A17, M3, M3 Pro, M3 Max (released in fall 2023).
- Added a check for iOS version 16.5 beta 4. This version patched the exploit after our report to Apple.
Why does the exploit need to check for iOS 17.2 and newer CPUs if the targeted vulnerabilities were fixed in iOS 16.5 beta 4? The answer can be found by examining other exploits: they are all based on the same source code. The only difference is in the vulnerabilities they exploit, so these checks were added to support the newer exploits and appeared in the older version after recompilation.
Launcher
The launcher is responsible for orchestrating the post-exploitation activities. It also uses the kernel exploit and the interface it provides. However, since the exploit creates special kernel objects during its execution that provide the ability to read and write to kernel memory, the launcher simply reuses these objects without the need to trigger vulnerabilities and go through the entire exploitation path again. The launcher cleans up exploitation artifacts, retrieves the process name for injection from a config with the 0xDEADD00F magic number, injects a stager into the target process, uses it to execute itself, and launches the implant.
Conclusions
This case demonstrates once again the dangers associated with such malicious tools that lie in their potential wide usage. Originally developed for cyber-espionage purposes, this framework is now being used by cybercriminals of a broader kind, placing millions of users with unpatched devices at risk. Given its modular design and ease of reuse, we expect that other threat actors will begin incorporating it into their attacks. We strongly recommend that users install the latest security updates as soon as possible, if they have not already done so.

