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 __cfstringAs 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 dataOnce 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:
- Attempts to unhook any debugger by calling
ptrace
with PT_DENY_ATTACH
as a request parameter. - Checks if some exceptional ports are open by calling the
task_get_exception_ports
function - Checks whether the debugger is connected, as shown in the figure below, by checking for the presence of the
P_TRACED
flag in the current process.
Figure 3. Verifying debugger connectivity using the sysctl functionIf 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.
- daff.faybilodeau [.] com
- sarc.onteagleroad [.] com
- au.charlineopkesston [.] com
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 variableIn 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 functionThe 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 .