Unraveling the techniques of Mac ransomware
Ransomware continues to be one of the most prevalent and impactful threats affecting organizations, with attackers constantly evolving their techniques and expanding their tradecraft to cast a wider net of potential targets. This is evident in the range of industries, systems, and platforms affected by ransomware attacks. Understanding how ransomware works across these systems and platforms is critical in protecting today’s hybrid device and work environments.
This blog provides details from our analysis of known ransomware families affecting macOS devices. As in other platforms, the initial vector of Mac ransomware typically relies on user-assisted methods like downloading and running fake or trojanized applications. It can, however, also arrive as a second-stage payload dropped or downloaded by other malware or part of a supply chain attack. Once running on a device, ransomware attacks usually comprise gaining access, execution, encrypting target users’ files, and notifying the target with a ransom message.
To perform these actions, malware creators abuse legitimate functionalities and devise various techniques to exploit vulnerabilities, evade defenses, or coerce users to infect their devices. We describe these techniques in detail below, based on our analysis of four Mac ransomware families: KeRanger, FileCoder, MacRansom, and EvilQuest. In particular, we take a deeper look at EvilQuest and one of its variants that had its ransomware component removed but was further improved with additional techniques and anti-analysis logic.
While these malware families are old, they exemplify the range of capabilities and malicious behavior possible on the platform. Building durable detections for these techniques will help improve defenses for devices and networks against ransomware and other threats. As with any security research in Microsoft, this in-depth analysis of malware techniques informs the protection we provide through solutions like Microsoft Defender for Endpoint on Mac. We’re sharing this information with the rest of the community as a technical reference that researchers can use and build upon to understand Mac threats and improve protections.
Targeting which files to encrypt is the most important step for any ransomware. We have seen various ways through which ransomware families have enumerated files and directories on Mac:
Using the Find binary
FileCoder and MacRansom use the find utility to search for files to encrypt. find is a common utility binary that is generally found across many Unix based systems like macOS, Linux, etc. and incorporates many features that could help attackers to search for and select files. The output of the command is then passed as an argument to the function or binary that carries out the encryption of the files.
Figure 1 shows part of the command used by FileCoder. It searches the “/Users” and “/Volumes” directories by invoking the said command twice, with a change on the path being enumerated and excluding its README file while searching the “/Users” path.
In the case of MacRansom, it searches for files in “/Volumes” and the current user’s directory. It uses -type f to include regular files, -size +8c to select files that are greater than 8 bytes, -user `whoami` to select files that belong to the current user, and -perm -u=r to get files for which the current user has readable permission. The output of the command in Figure 2 is then passed to another instance of the malware.
Using library functions opendir, readdir, and closedir
KeRanger and EvilQuest use library functions to get the directory listing. It uses a sequence of opendir(), readdir(), and closedir() to get the list of files.
First, it uses opendir() to open a directory by specifying the dirname. The handle returned from the opendir() function is used by the readdir() function to scan files. readdir() returns NULL if it reaches the end of the directory. It uses closedir() at the end to close the handle to the directory.
Using the NSFileManager class through Objective-C
There are open-source proofs-of-concept (POCs) and scripts where Objective-C functions are used to enumerate files. For example, the Gopher POC uses this technique to scan for .docx files in the User’s Documents directory.
In this technique, NSDirectoryEnumerator object is used to enumerate the directory’s contents, while the path is specified in the enumeratorAtPath: method. The function returns the enumerator, which is used to get all the paths of files and directories.
This method is unique to the Gopher POC and is not found in the four ransomware families we analyzed.
Malware creators deploy various anti-analysis techniques to evade or prevent the analysis of files by either analysts or automated analysis systems such as sandboxes. Among the Mac ransomware we studied, KeRanger, MacRansom, and EvilQuest employ hardware-based checks or use specific code apart from the usual obfuscation of strings to avoid analysis.
Checking a device’s hardware model
This technique (T1497.001), used by MacRansom, involves getting the hardware model of the system and checking a substring to detect if the malware is running in a virtual environment. Running inside a virtual machine (VM) often indicates that the malware is being analyzed by analysts or in a sandbox.
The result of the command on a host device contains the substring “Mac”, whereas the result on a Parallels VM setup doesn’t. The malware stops if it detects its presence in a virtual environment.
Checking the logical and physical processors of a device
MacRansom uses this technique (T1497.001) to check the count of the logical and physical CPU of the device.
In this case, a host device’s logical CPU count is usually twice the physical CPU count, whereas the values are the same for a VM instance. The command above divides the values of these two counts and compares them with 2. It makes the comparison to determine if the malware is running in a virtual instance or not.
Checking the MAC OUI of the device
This technique (T1497.001), used by EvilQuest variants, involves checking the MAC organizational unique identifier (OUI) prefix, which comprises the first 24 bits of a MAC address, to determine the device vendor. Checking the OUI is another technique to determine if the malware is running in a virtual environment.
Figure 7 shows the EvilQuest code that gets the MAC address of the en0 network interface, and compares the first three bytes with the OUI values hardcoded in EvilQuest. The values (v8, v7, and v6 in Figure 7) are attributed to many known virtualization platforms such as Parallels, VirtualBox, and VMware.
Checking the device’s CPU count and memory size
Analysis environments, specifically automated ones, are often deployed with minimal CPU and memory. EvilQuest checks the device’s CPU and memory size (T1497.001) to ensure it’s not running in a virtual environment.
The malware uses three different methods to check the number of CPUs. The first method uses the sysctl function by passing the MIB (Management Information Base) structure containing CTL_HW and HW_AVAILCPU identifiers. If this first method fails, the malware uses the second method where it replaces HW_AVAILCPU with HW_NCPU. If the second method also fails, it uses the command “sysctl -n hw.ncpu” as a third method to get the CPU count. EvilQuest further checks if the value of the CPU count is less than 2, which might indicate a virtual instance deployed with minimal hardware.
EvilQuest also checks the device’s physical memory size to avoid analysis environments. It uses sysctl function with the MIB structure CTL_HW and HW_MEMSIZE constants to check the physical RAM size. The result is then compared further with the size of 1GB, which might indicate a virtual instance.
Malware creators often use the delayed execution (T1497.003) technique to prevent automated analysis systems from detecting the malware’s actual behavior. KeRanger uses this delayed execution technique where, upon launching, it sleeps for three days before performing its malicious routines.
This technique (T1622), used by both EvilQuest and MacRansom, is a known anti-debugging trick that prevents debuggers from attaching to the current malware process. It is used to avoid the debugging of malware files.
As seen in MacRansom’s code (Figure 11), it first opens the handle to itself, where the ptrace symbol is searched, and the address is retrieved. It is then called with the argument 0x1F, a constant for PT_DENY_ATTACH.
EvilQuest implements the same technique in two ways. One method is a simple call to the ptrace function with the argument 0x1F as above. In another variant, the logic is implemented using syscall. This method invokes ptrace through syscall with the PT_DENY_ATTACH flag.
Additionally, the EvilQuest variant also verifies if the PT_DENY_ATTACH operation is successful. To do so, it first registers a handler for the signal SIGSEGV and calls the ptrace method again with the argument PT_ATTACH. This ptrace() call with PT_ATTACH flag throws a SIGSEGV signal if it fails to attach to the process, which further invokes the handler. The handler sets a variable that is checked next to determine the success of PT_DENY_ATTACH operation.
EvilQuest uses this technique (T1622) to check whether it is being debugged. The technique is used to get the process structure and check for the P_TRACED flag. If the flag is found to be set, it indicates that the process is being debugged. The malware then alters its behavior to avoid analysis.
Malware using this technique (T1497.003) checks if it is running in a sandbox by checking if the device’s sleep function is patched. Sandboxes attempt to patch the sleep function to avoid execution delay, which is used by some malware. Ransomware like EvilQuest sleeps for a specified time between two time() calls. Next, the difference in the timestamp is calculated and checked with the duration specified in sleep() call.
Malware commonly uses persistence to ensure it runs even after a system restart. Among the Mac ransomware families analyzed, we’ve seen persistence techniques in EvilQuest and MacRansom. The following are persistence techniques implemented by these malware families.
Creating launch agents or launch daemons
Creating Launch Agents (T1543.001) or Launch Daemons (T1543.004) is a persistence method that uses launch items. This technique utilizes a property list (PLIST) file, which is used in macOS to specify configurations and properties in respective directories to gain persistence. EvilQuest can create both Launch Agent and Launch Daemon files, while MacRansom typically creates a Launch Agent file.
The ProgramArguments key in the PLIST file (Figure 15) specifies the process to run with arguments if any, and RunAtLoad and KeepAlive keys are used to ensure that the process is continuously running.
Using kernel queues
The kernel queue (kqueue) provides a way for an application to get notifications based on various conditions and events. In the case of EvilQuest, it uses this method to restore itself based on notification it receives in case any modifications are made to the list of files it wants to monitor. Different EvilQuest variants use different versions of this implementation.
It first creates the kernel event (kevent) queue using the kqueue() system call. Next, it forms a structure for each file containing its file handle and the required filters and flags to register the files to monitor. The pointer to this array of structures is passed in the changelist argument to the kevent() call. The eventlist parameter then stores any changes observed. The malware invokes the kevent() call in a loop. If any modifications are made to the files being monitored, EvilQuest tries to restore them.
The ransomware families we analyzed often share similar anti-analysis and persistence techniques. However, these same ransomware families differ in encryption logic. Some use AES-RSA encryptions, while others use system utilities, XOR routine, or custom encryption logic to encrypt files. These encryption methods range from in-place modification to creating a new file while deleting the original one. Common among the ransomware observed is adding a new extension or simply encrypting the file without adding any new one.
FileCoder ransomware uses the ZIP utility to encrypt files. Files enumerated using the find utility are passed to the ZIP utility with the flag -0 (no compression) and -P (password), along with a randomly generated key for encryption.
FileCoder appends the .crypt extension to encrypted files (Figure 17). It removes the original file and changes the timestamp of the newly created file, which also works as an evasion tactic. FileCoder only encrypts files present in the /Users and /Volumes directories. It invokes the command twice with the path change being enumerated. While enumerating files in the /Users directory, it skips its dropped ransom note.
KeRanger, on the other hand, uses AES encryption in Cipher block chaining (CBC) mode to encrypt files. It leverages the mbedtls library for performing cryptographic functions.
The process begins by generating a key used for AES and hash-based message authentication code (HMAC). It generates a random number that is fed to the digest and an initialization vector, a value calculated by KeRanger and utilized in its key generation process. The result is then used as a key in the next iteration, along with the same random number. This process is done eight times, after which the result is used to set the key.
It then encrypts the random number generated earlier with the RSA key received from the server. To encrypt the files, it uses the generated AES key. It also calculates the HMAC of the original file content, which is written to the output file, along with keying information (data that can be used to decrypt the encrypted files such as key length, the encrypted random number, the initial vector, etc.) and encrypted content.
MacRansom uses a symmetric algorithm for encrypting files and decrypting its ransom note “._README_”. The ransom note contains encrypted data which MacRansom decrypts using a hardcoded key. It uses separate keys for encrypting the files and decrypting its ransom note.
First, it enumerates the target files using the find utility and passes it to another instance of the malware as mentioned in Figure 2. This new malware instance calculates the encryption key first by permuting a hardcoded key with a random number.
MacRansom reads the file’s content and encrypts it with the permuted key generated earlier. In the process of encryption, if MacRansom encounters its ransom note by checking the filename which is “._README_”, it uses a separate hardcoded key to decrypt its content.
EvilQuest uses a custom symmetric key encryption routine to encrypt target files. For each target file, the malware creates a temporary file name using the format “.<FILENAME>.e” and then checks if the file has already been encrypted by checking the presence of the marker 0xDDBEBABE. If not, it reads the target file, encrypts the content, and writes the content to the temporary file. After encrypting the content, the malware encodes the file encryption key and appends the keying information to the file along with the marker. It then proceeds to delete the target file and rename the temporary file to the original target file’s name.
EvilQuest’s other capabilities
Further analysis of some variants of EvilQuest shows interesting capabilities on top of encrypting files. In this section, we discuss other behavior that we have observed in the two EvilQuest variants analyzed apart from their encryption routine. We noted behaviors such as file infection, keylogging, info stealing, disabling security solutions, and in-memory execution.
Over the past years, we have observed many variants of EvilQuest that removed its ransomware component. Tracking behavior changes in malware is important to understand how these affect devices and data and how to prevent these attacks effectively. These additions and changes in behavior might also provide clues about EvilQuest’s future attacks.
EvilQuest can infect Mach-O files by inserting its code (T1554). To identify files to infect, it scans through the /Users directory. It calls a routine for each file found. This routine checks the magic bytes of the file to determine whether the file is a Mach-O binary. It also skips the file if the path contains .app or if the file size exceeds 25 MB.
After scanning and finding target files, EvilQuest prepends its code to the target file and appends a trailer, which contains data such as marker and offset to the original binary code. EvilQuest uses the marker 0xDEADFACE in the trailer data to check whether a file is infected.
If any of the infected file is executed, EvilQuest has checks to identify, if it’s running from an infected file and to execute the original binary using the following logic:
- Extract the trailer to check if the current process is infected.
- Go to the offset present in the trailer.
- Read the original binary content from the offset of the calculated size to a buffer.
- Format and form another path: <PATH>/.<FILE_NAME>1.
- The original binary content is written in the above file.
- Provide executable permissions to this newly created file and execute the file.
We observed two mechanisms of keylogging (T1056.001) in two EvilQuest variants we analyzed. The first mechanism uses the API CGEventTapCreate, while the second uses the IOHIDManagerCreate API.
Using the CGEventTapCreate API
This API creates an event tap to monitor human interface devices (HID) like keyboards. Keylogging starts upon receiving commands from a command and control (C2) server.
The malware creates an event tap using CGEventTapCreate and uses CGEventTapEnable to activate it. The callback function seen in this EvilQuest variant converts the constant and prints it on the standard output.
Using the IOHIDManagerCreate API
This API is used to communicate with and monitor HID devices. To achieve this, EvilQuest uses the following functions:
- It uses IOHIDManagerCreate to create the HID manager handle.
- CreateMatchingDirectory method is used with argument value 6 (kHIDUsage_GD_Keyboard) for setting the device type filtering.
- It uses IOHIDManagerRegisterInputValueCallback to set the callback function.
- IOHIDManagerOpen further opens the HIDManager.
- IOHIDManagerScheduleWithRunLoop for scheduling the manager with run loop.
Figure 27 shows the callback code that is specified in the IOHIDManagerRegisterInputValueCallback function. It uses IOHIDValueGetElement and IOHIDElementGetUsage to get the usage for the element. It then gets the ASCII mapping, which is written to the .DS_State file.
Disabling security programs
EvilQuest tries to stop security processes to evade detection. Microsoft Defender for Endpoint on Mac’s tamper protection feature safeguards the application from this disabling behavior.
First, it gets the process list by forming the MIB structure, which contains CTL_KERN, KERN_PROC, KERN_PROC_ALL identifiers. The first systcl call gets the output’s size, which is then passed to the second sysctl call. This returns the structure for each process.
Next, it parses these structures and gets the process ID, passed along with CTL_KERN,KERN_PROCARGS2 identifiers to get the process arguments. The results are then searched against known patterns for security programs that are hardcoded in EvilQuest. Finding a matching pattern in the hardcoded list leads to EvilQuest stopping the process and removing executable permissions from the process file.
This technique (T1620) is a way to execute any file from memory without dropping hence, leaving no trace of the malware on disk. EvilQuest uses the following APIs to implement in-memory execution:
- NSCreateObjectFileImageFromMemory – used for creating an object file image from the data present in memory
- NSLinkModule – used to link the object file image
- NSLookupSymbolInModule – used for looking for a specific symbol
- NSAddressOfSymbol – used to get the address of the symbol.
The address of the function returned from the previous call is then executed.
Defending against macOS ransomware
Ransomware continues to be one of the most significant threats affecting any platform. Our analysis of ransomware on Mac operating systems shows how its creators use various techniques to remain hidden from automated analysis systems or make manual inspection by analysts challenging. Understanding ransomware routines and their effects on any device or platform is essential for individual users to take steps toward device and data protection. Organizations can benefit from knowing these malicious behaviors and protect their networks in the age of securing multiple systems and devices operating in their networks.
Defenders can take the following mitigation steps to defend against these ransomware attacks:
- Install apps from trusted sources only, such as a software platform’s official app store.
- Restrict access to privileged resources like LaunchDaemons or LaunchAgents folders and sudoers files through OSX enterprise management solutions. This helps mitigate common persistence and privilege escalation techniques.
- Use web browsers like Microsoft Edge—available on macOS and various platforms—that support Microsoft Defender SmartScreen. SmartScreen identifies and blocks malicious websites, including phishing sites, scam sites, and sites that contain exploits and host malware.
- Run the latest version of your operating systems and applications. Deploy the latest security updates as soon as they become available. These ensure your device is benefiting from the latest cloud-delivered protections.
- Use Microsoft Defender for Endpoint on Mac, which detects, stops, and quarantines the malware discussed in this blog using the following detection names:
Microsoft Defender for Endpoint tracks the techniques mentioned in the MITRE ATT&CK® tactics and techniques table below and creates alerts where applicable. Defender for Endpoint provides cross-platform defense and a unified investigation experience that gives organizations visibility across all endpoints in the network.
MITRE ATT&CK® tactics and techniques observed
- T1204.002 User Execution: Malicious File
- T1059.002 Command and Scripting Interpreter: AppleScript
- T1569.001 System Services: Launchctl
- T1543.001 Create or Modify System Process: Launch Agent
- T1543.004 Create or Modify System Process: Launch Daemon
- T1554 Compromise Client Software Binary
- T1548.003 Abuse Elevation Control Mechanism: Sudo and Sudo caching
- T1543.004 Create or Modify System Process: Launch Daemon
- T1140 Deobfuscate/Decode Files or Information
- T1222.002 File and Directory Permissions Modification: Linux and MAC File and Directory Permissions
- T1562.001 Impair Defences: Disable or Modify tools
- T1070.004 Indicator Removal on Host: File Deletion
- T1070.006 Indicator Removal on Host: Timestomp
- T1036.005 Masquerading: Match Legitimate Name or Location
- T1083 File and Directory Discovery
- T1057 Process Discovery
- T1518.001 Software Discovery: Security Software Discovery
- T1082 System Information Discovery
- T1033 System Owner/User Discovery
- T1005 Data from Local System
Command & Control
- T1071.001 Application Layer Protocol: Web protocols
- T1132.002 Data Encoding: Non-Standard Encoding
- T1105 Ingress Tool Transfer
- T1041 Exfiltration over C2 channel
- T1486 Data Encrypted for Impact
Indicators of compromise
- b34738e181a6119f23e930476ae949fc0c7c4ded6efa003019fa946c4e5b287a (EvilQuest)
- bcdb0ca7c51e9de4cf6c5c346fd28a4ed28e692319177c8a94c86dc676ee8e48 (EvilQuest variant)
- 617f7301fd67e8b5d8ad42d4e94e02cb313fe5ad51770ef93323c6115e52fe98 (MacRansom)
- d19b903adbd0f8c119d0d8f25b194bdd24b737357a517f23ca5cdc6c75b35038 (FileCoder)
- 31b6adb633cff2a0f34cefd2a218097f3a9a8176c9363cc70fe41fe02af810b9 (KeRanger)
READ MORE HERE