{"id":110050,"date":"2023-06-21T10:00:57","date_gmt":"2023-06-21T10:00:57","guid":{"rendered":"https:\/\/kasperskycontenthub.com\/securelist\/?p=110050"},"modified":"2023-06-21T14:58:17","modified_gmt":"2023-06-21T14:58:17","slug":"triangledb-triangulation-implant","status":"publish","type":"post","link":"https:\/\/securelist.com\/triangledb-triangulation-implant\/110050\/","title":{"rendered":"Dissecting TriangleDB, a Triangulation spyware implant"},"content":{"rendered":"

Over the years, there have been multiple cases when iOS devices were infected with targeted spyware such as Pegasus, Predator, Reign and others. Often, the process of infecting a device involves launching a chain of different exploits, e.g. for escaping the iMessage sandbox while processing a malicious attachment, and for getting root privileges through a vulnerability in the kernel. Due to this granularity, discovering one exploit in the chain often does not result in retrieving the rest of the chain and obtaining the final spyware payload. For example, in 2021, analysis of iTunes backups helped to discover an attachment containing the FORCEDENTRY<\/a> exploit. However, during post-exploitation, the malicious code downloaded a payload from a remote server that was not accessible at the time of analysis. Consequently, the analysts lost<\/a> “the ability to follow the exploit.”<\/p>\n

In researching Operation Triangulation, we set ourselves the goal to retrieve as many parts of the exploitation chain as possible. It took about half a year to accomplish that goal, and, after the collection of the chain had been completed, we started an in-depth analysis of the discovered stages. As of now, we have finished analyzing the spyware implant and are ready to share the details.<\/p>\n

\"\"<\/a>

The Operation Triangulation infection chain<\/p><\/div>\n

The implant, which we dubbed TriangleDB, is deployed after the attackers obtain root privileges on the target iOS device by exploiting a kernel vulnerability. It is deployed in memory, meaning that all traces of the implant are lost when the device gets rebooted. Therefore, if the victim reboots their device, the attackers have to reinfect it by sending an iMessage with a malicious attachment, thus launching the whole exploitation chain again. In case no reboot occurs, the implant uninstalls itself after 30 days, unless this period is extended by the attackers.<\/p>\n

Meet TriangleDB<\/h2>\n

The TriangleDB implant is coded using Objective-C, a programming language that preserves names of members and methods assigned by the developer. In the implant’s binary, method names are not obfuscated; however, names of class members are uninformative acronyms, which makes it difficult to guess their meaning:<\/p>\n\n\n\n\n
\n

Class method examples<\/strong><\/p>\n<\/td>\n

\n

Class member examples<\/strong><\/p>\n<\/td>\n<\/tr>\n

\n

-[CRConfig populateWithFieldsMacOSOnly]\n

-[CRConfig populateWithSysInfo]\n

-[CRConfig extendFor:]\n

-[CRConfig getCInfoForDump]\n

+[CRConfig sharedInstance]\n

+[CRConfig unmungeHexString:]\n

-[CRConfig init]\n

-[CRConfig getBuildArchitecture]\n

-[CRConfig cLS]\n

-[CRConfig setVersion]\n

-[CRConfig swapLpServerType]\n

-[CRConfig setLpServerType:]\n<\/td>\n

\n

NSString *pubKI;<\/p>\n

NSData *pubK;<\/p>\n

signed __int64 iDa;<\/p>\n

signed __int64 uD;<\/p>\n

NSString *deN;<\/p>\n

NSSTring *prT;<\/p>\n

NSString *seN;<\/p>\n

NSString *uDI;<\/p>\n

NSString *iME;<\/p>\n

NSString *meI;<\/p>\n

NSString *osV;<\/p>\n

CRPwrInfo *pwI;<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n

In some cases, it is possible to guess what the acronyms mean. For example, osV is the iOS version, and iME contains the device’s IMEI.<\/p>\n

The strings in the implant are HEX-encoded and encrypted with rolling XOR:<\/p>\n

id +[CRConfig unmungeHexString:](id a1, SEL a2, id stringToDecrypt) {\r\n  \/\/ code omitted\r\n  while (1) {\r\n\thexByte[0] = stringBytes[i];\r\n\thexByte[1] = stringBytes[i + 1];\r\n\tencryptedByte = strtoul(hexByte, &__endptr, 16);\r\n\tif (__endptr == hexByte) \r\n          break;\r\n\ti += 2LL;\r\n\tif (j)\r\n  \t    decryptedString[j] = encryptedByte ^ previousByte;\r\n\telse\r\n  \t    decryptedString[0] = encryptedByte;\r\n\t++j;\r\n\tpreviousByte = encryptedByte;\r\n\tif (i >= stringLength) \r\n          break;\r\n  }\r\n  decryptedString[j] = 0;\r\n  \/\/ code omitted\r\n}\r\n<\/pre>\n

The rolling XOR algorithm implemented in the implant for string decryption<\/em><\/p>\n

C2 communications<\/h2>\n

Once the implant launches, it starts communicating with the C2 server, using the Protobuf library for exchanging data. The configuration of the implant contains two servers: the primary and the fallback (contained in the lS and lSf configuration fields). Normally, the implant uses the primary server, and, in case of an error, it switches to the fallback server by invoking the -[CRConfig swapLpServerType:] method.<\/p>\n

Additionally, the sent and received messages are encrypted with symmetric (3DES) and asymmetric (RSA) cryptography. All messages are exchanged via the HTTPS protocol in POST requests, with the cookie having the key g and a value that is a digit string from the pubKI configuration parameter.<\/p>\n

The implant periodically sends heartbeat beacons that contain system information, including the implant version, device identifiers (IMEI, MEID, serial number, etc.) and the configuration of the update daemon (whether automatic downloads and installations of updates are enabled).
\n

\"Heartbeat<\/a>

Heartbeat beacon snippet, implant v1.7.0.5 running on iOS 15.3.1<\/p><\/div>\n

TriangleDB commands<\/h2>\n

The C2 server responds to heartbeat messages with commands. Commands are transferred as Protobuf messages that have type names starting with CRX. The meaning of these names is obscure: for example, the command listing directories is called CRXShowTables, and changing C2 server addresses is handled by the command CRXConfigureDBServer. In total, the implant we analyzed has 24 commands designed for:<\/p>\n