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.

File enumeration     

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.

Screenshot of FileCoder’s enumeration logic.
Figure 1. FileCoder’s enumeration logic

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.

Screenshot of MacRansom’s enumeration logic
Figure 2. MacRansom’s enumeration logic

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.

Screenshot of EvilQuest's code showing library functions used to enumerate files.
Figure 3. Library functions used in EvilQuest

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.

Screenshot of Gopher POC's code using the NSFileManager to enumerate files.
Figure 4. Gopher’s use of NSFileManager

This method is unique to the Gopher POC and is not found in the four ransomware families we analyzed.

Anti-analysis techniques

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.

Hardware-based checks

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.

Screenshots of results of checking the hardware model of a MacBook Pro and a device that is running macOS on a virtual machine.
Figure 5. The command used by MacRansom (above) determines the environment it is running on. Below the command is the comparison of the results between checking the hardware model of a MacBook Pro (left) and a Mac OS running on Parallels VM (right)

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.

Screenshots of results of the number of logical and physical CPUs in a MacBook Pro and in a macOS hosted on a Parallels virtual machine.
Figure 6. The command used by MacRansom’s  (above) counts logical and physical CPUs present in the device. Below that is the logical and physical processors check comparison between a MacBook Pro (left) and a Mac OS running on Parallels VM (right)

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.

Screenshot of EvilQuest code checking the MAC OUI prefix of a device.
Figure 7. EvilQuest code that checks the MAC OUI prefix

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.

Screenshot of EvilQuest's code checking for CPU count on a device.
Figure 8. EvilQuest code that checks for CPU count

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.

Screenshot of EvilQuest's code checking a device's physical memory size.
Figure 9. EvilQuest code to check the device’s physical memory size

Code-related checks

Delayed execution

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.

Screenshot of KeRanger's code used in delaying its execution.
Figure 10. KeRanger code used to delay its execution

PT_DENY_ATTACH (PTRACE)

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.

Screenshot of MacRansom's code that invokes the PT_DENY_ATTACH argument.
Figure 11.  Code in MacRansom where it invokes ptrace with PT_DENY_ATTACH argument

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.

Screenshot of EvilQuest's code where it uses syscall.
Figure 12. Code in an EvilQuest variant where it uses Syscall(ptrace) to avoid debuggers  

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.

P_TRACED flag

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.

Screenshot of EvilQuest's code checking for the P_TRACED flag.
Figure 13. Code in an EvilQuest variant where it checks for the P_TRACED flag

Time-based check

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.

Screenshot of EvilQuest's code where it checks the sleep patching function.
Figure 14. EvilQuest code that checks patching of sleep function

Persistence

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. 

Screenshot of EvilQuest's launch daemon PLIST file.
Figure 15. EvilQuest’s launch daemon PLIST 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.

Screenshot of EvilQuest's file monitoring initialization and file restoring codes.
Figure 16. EvilQuest variant’s codes used to initialize file monitoring (left) and to restore files after modification (right)  

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.

Encryption

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

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.

Screenshot of FileCoder’s encryption logic
Figure 17. FileCoder’s encryption logic

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

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.

Illustration of how KeRanger generates its key.
Figure 18. KeRanger’s key generation process

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.

Screenshot of KeRanger's code showing its encryption logic.
Figure 19. KeRanger’s encryption logic

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

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.

Screenshot of MacRansom's code used to generate keys.
Figure 20. MacRansom’s key generation logic

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.

Screenshot of MacRansom's encryption logic.
Figure 21. MacRansom’s encryption logic

EvilQuest

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.

Screenshot of EvilQuest's code showing its encryption process
Figure 22. EvilQuest’s encryption process

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.

File infection

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.

Screenshot of EvilQuest's code used to check for magic bytes.
Figure 23. EvilQuest’s code checking for the magic bytes

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.

Illustration of a file infected by EvilQuest's code. The illustration shows the last three parts of the file as the trailer, and the code offset is written in the original binary's code.
Figure 24. Structure of a file infected by EvilQuest

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:

  1. Extract the trailer to check if the current process is infected.
  2. Go to the offset present in the trailer.
  3. Read the original binary content from the offset of the calculated size to a buffer.
  4. Format and form another path: <PATH>/.<FILE_NAME>1.
  5. The original binary content is written in the above file.
  6. Provide executable permissions to this newly created file and execute the file.

Keylogging

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.

Screenshot of EvilQuest's code used for logging keystrokes.
Figure 25. EvilQuest code for logging keystrokes using the CGEventTapCreate API

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.
Screenshot of an EvilQuest variant's code that uses the IOHIDManager API to monitor devices.
Figure 26. An EvilQuest variant using the IOHIDManager API

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.

Screenshot of an EvilQuest variant's code using the callback function.
Figure 27. EvilQuest’s callback function

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.

Screenshot of an EvilQuest variant's code getting the structure of running processes on the device.
Figure 28. EvilQuest getting the structure of running processes on the device

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.

Screenshot of an EvilQuest variant's code where it stops security processes.
Figure29. Code that stops the security process EvilQuest finds

In-memory execution

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.

Screenshot of an EvilQuest variant's API use for in-memory execution.
Figure 30. EvilQuest’s API use for its in-memory execution

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:
    • Ransom:MacOS/EvilQuest
    • Ransom:MacOS/Filecoder.YC!MTB
    • Ransom:MacOS_X/Ratatonilly.A
    • Ransom:MacOS/Crypat.A!MTB
    • Ransom:MacOS_X/KeRanger.A

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.

Screenshot of Mac ransomware-related alerts on Microsoft Defender for Endpoint.
Figure 31. Mac ransomware-related alerts on Microsoft Defender for Endpoint

MITRE ATT&CK® tactics and techniques observed

Execution

  • T1204.002 User Execution: Malicious File
  • T1059.002 Command and Scripting Interpreter: AppleScript
  • T1569.001 System Services: Launchctl

Persistence

  • T1543.001 Create or Modify System Process: Launch Agent
  • T1543.004 Create or Modify System Process: Launch Daemon
  • T1554 Compromise Client Software Binary

Privilege Escalation

  • T1548.003 Abuse Elevation Control Mechanism: Sudo and Sudo caching
  • T1543.004 Create or Modify System Process: Launch Daemon

Defense Evasion

  • T1140 Deobfuscate/Decode Files or Information
  • T1222.002 File and Directory Permissions Modification: Linux and MAC File and Directory Permissions

Modification

  • 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

Discovery

  • T1083 File and Directory Discovery
  • T1057 Process Discovery
  • T1518.001 Software Discovery: Security Software Discovery
  • T1082 System Information Discovery
  • T1033 System Owner/User Discovery

Collection

  • 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

Exfiltration

  • T1041 Exfiltration over C2 channel

Impact

  • T1486 Data Encrypted for Impact

Indicators of compromise

  • b34738e181a6119f23e930476ae949fc0c7c4ded6efa003019fa946c4e5b287a (EvilQuest)
  • bcdb0ca7c51e9de4cf6c5c346fd28a4ed28e692319177c8a94c86dc676ee8e48 (EvilQuest variant)
  • 617f7301fd67e8b5d8ad42d4e94e02cb313fe5ad51770ef93323c6115e52fe98 (MacRansom)
  • d19b903adbd0f8c119d0d8f25b194bdd24b737357a517f23ca5cdc6c75b35038 (FileCoder)
  • 31b6adb633cff2a0f34cefd2a218097f3a9a8176c9363cc70fe41fe02af810b9 (KeRanger)

READ MORE HERE