📜 ⬆️ ⬇️

OceanLotus: Malvari update for macOS

In March 2019, VirusTotal, a popular online scanning service, downloaded a new malware sample for macLos of the OceanLotus cyber group. The backdoor executable file has the same capabilities as the previous version of Malvari for macOS we studied, but its structure has changed and it has become more difficult to detect. Unfortunately, we could not find a dropper associated with this sample, so we don’t yet know the infection vector.

We recently published a post about OceanLotus and how operators are trying to ensure persistence, speed up code execution and minimize traces of presence on Windows systems. It is also known that this cyber group has a component for macOS. This post describes in detail the changes in the latest version of Malware for macOS in comparison with the previous version ( described by Trend Micro ), and also describes how to analyze the decoding of strings with the help of the IDA Hex-Rays API.


Analysis


The following three sections describe the analysis of the sample with the SHA-1 E615632C9998E4D3E5ACD8851864ED09B02C77D2 . The file is called flashlightd , ESET antivirus products detect it as OSX / OceanLotus.D.
')

Anti-debug and sandbox protection


Like all OceanLotus macOS binaries, the sample is packaged with UPX, but most packer identification tools do not recognize it as such. Probably because they mainly contain a signature that depends on the presence of the string “UPX”, moreover, Mach-O signatures are less common and are not updated so often. This feature makes static detection difficult. Interestingly, after unpacking, the entry point is at the beginning of the __cfstring section in the .TEXT segment. This section has flag attributes, as shown in the figure below.


Figure 1. MACH-O section attributes __cfstring

As shown in Figure 2, the location of the code in the __cfstring section allows __cfstring to fool some disassembling tools by displaying the code as strings.


Figure 2. Backdoor code defined by IDA as data

Once launched, the binary file creates a stream as a debug protection tool, the sole purpose of which is to constantly check for the presence of a debugger. For this thread:



Figure 3. Verifying debugger connectivity using the sysctl function

If the watchdog detects the presence of a debugger, the exit function is called. In addition, the sample then checks the environment by executing two commands:

ioreg -l | grep -e "Manufacturer" sysctl hw.model

After that, the sample checks the return value against a hard-coded list of strings of known virtualization systems: acle , vmware , virtualbox, or parallels . Finally, the following command checks if the machine is one of the following “MBP”, “MBA”, “MB”, “MM”, “IM”, “MP” and “XS”. These are system model codes, for example, “MBP” means MacBook Pro, “MBA” means MacBook Air, etc.

system_profiler SPHardwareDataType 2>/dev/null | awk '/Boot ROM Version/ {split($0, line, ":");printf("%s", line[2]);}

Key additions


Despite the fact that backdoor teams have not changed since Trend Micro research, we noticed several other modifications. The C & C servers used in this sample are fairly new; their creation date is 10/22/2018.


URL resource changed to /dp/B074WC4NHW/ref=gbps_img_m-9_62c3_750e6b35 .
The first packet sent to the C & C server contains more information about the host machine, including all the data collected by the commands in the table below.



In addition to this configuration change, the sample does not use the libcurl library for network filtering, but an external library. To find it, the backdoor attempts to decrypt each file in the current directory using AES-256-CBC with the key gFjMXBgyXWULmVVVzyxy , supplemented with zeros. Each file is decrypted and saved as /tmp/store , and an attempt to load it as a library is made using the dlopen function. When a decryption attempt leads to a successful dlopen call, the backdoor retrieves the exported Boriry and ChadylonV , which appear to be responsible for the network interaction with the server. We do not have a dropper or other files from the original sample location, so we cannot analyze this library. Moreover, since the component is encrypted, a YARA rule based on these strings will not match the file found on the disk.

As described in the above article, cliendID is created. This identifier is the MD5 hash of the return value of one of the following commands:

- ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformSerialNumber/ { split($0, line, "\""); printf("%s", line[4]); }' ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformSerialNumber/ { split($0, line, "\""); printf("%s", line[4]); }'
- ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { split($0, line, "\""); printf("%s", line[4]); }' ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { split($0, line, "\""); printf("%s", line[4]); }'
- ifconfig en0 | awk \'/ether /{print $2}\' ifconfig en0 | awk \'/ether /{print $2}\' (get MAC address)
- unknown command (" \x1e\x72\x0a "), which is used in previous samples

Before hashing, a “0” or “1” character is added to the returned value, indicating root privileges. This clientID is stored in /Library/Storage/File System/HFS/25cf5d02-e50b-4288-870a-528d56c3cf6e/pivtoken.appex if the code is run as root or in ~ / Library / SmartCardsServices / Technology / PlugIns / drivers / snippets.ecgML in all other cases. The file is usually hidden with the _chflags function, its timestamp is changed using the touch –t command with a random value.

String decode


As in the previous versions, the strings are encrypted using AES-256-CBC (hexadecimal key: 9D7274AD7BCEF0DED29BDBB428C251DF8B350B92 supplemented with zeros, and IV is filled with zeros) using the CCCrypt function. The key is changed in comparison with previous versions, but since the group still uses the same string encryption algorithm, the decryption can be automated. In addition to this post, we are releasing an IDA script that uses the Hex-Rays API to decrypt strings present in a binary file. This script may help in the future analysis of OceanLotus and analysis of existing samples that we have not yet been able to obtain. At the core of the script is a universal method for obtaining the arguments passed to the function. In addition, he is looking for parameter assignments. The method can be reused to get a list of function arguments and then pass on a callback.

Knowing the prototype of the decrypt function, the script finds all the cross references to this function, all the arguments, then decrypts the data and places the plain text inside the comment at the cross reference. For the script to work properly, it must have the user alphabet set used by the base64 decoding function, and a global variable containing the key length (in this case, DWORD, see Figure 4) must be defined.


Figure 4. Definition of the global key_len variable

In the Function window, you can right-click the decryption function and click "Extract and Decrypt Arguments." The script should place the decrypted lines in the comments, as shown in Figure 5.


Figure 5. The decoded text is placed in the comments.

Thus, decrypted strings are conveniently placed together in the IDA xrefs window for this function, as shown in Figure 6.


Figure 6. Xrefs to f_decrypt function

The final script can be found on the Github repository .

Conclusion


As already mentioned, OceanLotus is constantly improving and updating its toolbox. This time, the cybergroup improved malware for working with Mac users. The code has not changed much, but since many Mac-users ignore products for safety, protection from detection is of secondary importance.

ESET products have already detected this file at the time of the study. Since the network library used for C & C communication is now encrypted on disk, the exact network protocol used by the attackers is not yet known.

Compromise indicators


Indicators of compromise, as well as the attributes of MITER ATT & CK are also available on GitHub .

Source: https://habr.com/ru/post/447530/


All Articles