The macOS threat landscape does not see action quite as often as the Windows threat landscape so when we at K7 Labs came across a new macOS ransomware sample in the wild we immediately notified the security community about it. Ransomware is actually pretty rare in the Mac world hence digging deeper into this malware sample was warranted.
As mentioned in the below tweet, the sample binary was supposedly found within a Google software program directory (based on the file path of the binary that was submitted to VirusTotal).
This prompted us to look for other packages that had such a binary component within themselves.
Similar binaries were then later uncovered within bundled pirated software packages by fellow researcher Thomas Reed. We then started to analyze one such package.
Examining the Malicious Package
The ransomware is bundled with pirated software as shown in Figure 1, which depicts the directory listing of files within the package. The ransomware executable is triggered by a postinstall script during the installation process, a standard trick adopted by Mac malware authors. Postinstall scripts are typically used by legitimate apps to trigger components after they have been installed.
In our case this postinstall script is what is going to take care of what happens to the bundled ransomware, so deserves a closer look.
Figure 2 shows the contents of the postinstall script. It is a basic shell script that first moves the file named “patch”, in our case the ransomware binary, from the bundle to the Library folder, and then removes the binary’s original directory. It then goes on to confer executable permissions on the file and launches it.
Once the ransomware binary gets executed it looks for certain command-line arguments which is apparent in the code block shown in Figure 3. The parameters are named “–silent”, “–noroot”, etc. For the present, we can speculate based on the names of the parameters that these are meant to define how the ransomware gets installed, i.e. silently infect or infect without root privileges respectively. These parameters are added in the ransomware’s persistence entries discussed later in this blog.
Environment and Context Checks
The first check that the malware does is to verify whether it is being run within a controlled environment. It does this by inserting a sleep function in between two time commands. If the sandbox automatically patches sleep functions found in malware then it would be discovered by this check. This is inferred from the code block in Figure 4.
Environment_Check – tick! Next it is time to move on to the Debugger_Check. The malware seeks to determine whether the debugging flag for the current process is set using the _sysctl function as shown in the code block in Figure 5.
In case the malware process is found to be in a debugged state, then further analysis is promptly ruptured by invoking the _ptrace function with the parameter PTRACE_DENY_ATTACH (1fh). This is depicted in the code block in Figure 6.
And last in the checklist of “Let me run in peace”, the malware goes on to check for any installed security products. The code block in Figure 7 shows how the ransomware gets the list of running processes on the host and cross-checks it with its own list of process names associated with well-known security products, e.g. Little Snitch, terminating them if found.
The malware then ensures persistence. It does this by copying itself to the ~/Library/AppQuest/ folder and achieves LaunchAgents or LaunchDaemon persistence based on the user privileges. One might recognise one of the command-line parameters that was discussed earlier in the plist file shown in Figure 8.
Encryption and Thereafter
Shown in Figure 9 is the function carve_target that encrypts the user files on the system. It first creates a temporary copy of the file that is to be encrypted and appends “.e” to the filename.
Once the encryption is done the ransomware adds the marker “BE BA BE DD” at the end of the file, and then the file is renamed to the original filename and moved back in place. The code to write the marker is shown in Figure 10.
Once all files are encrypted there are 18 beeps after which the customary ransom note/message is shown. An alert with text-to-speech is raised to inform the user about the encryption and then the ransomware note gets dropped onto the desktop.
The ransomware can also receive commands from a C&C server and perform operations such as executing commands, executing a payload directly in memory and keylogging. A typical Windows ransomware counterpart would “self destruct” once the deed is done, so this behaviour is quite unusual and curious; a ransomware behaving like a bot?
Shown in Figure 14 is the disassembled code of the _react_keys function which is an implementation of a simple keylogger using CGEventTap.
So, there were two types of binaries that have been mentioned thus far; one binary that we chanced upon in the wild, as mentioned in the tweet, and the other that was part of the pirated software package.
The ransomware binary mentioned in the tweet had a legitimate file, “GoogleSoftwareUpdateDaemon”, appended to it. Whereas in the scenario of the ransomware binary bundled along with pirated software, nothing was found appended.
Turns out the malware does an initial check for an appended file in the _extract_ei function. It reads the last 0x20 bytes of the file and looks for the “DEADFACE” magic. The 4 bytes prior to this is the size of the ransomware binary as highlighted in Figure 15. If an appended file exists then the malware alters its flow to a function named _persist_executable_frombundle as shown in Figure 16. This function takes care of extracting the ransomware binary from the bundle and ensures its persistence.
The ransomware part of the binary is copied to the “/Library/AppQuest/com.apple.questd” location and a LaunchAgents persistence “~/Library/LaunchAgents/com.apple.questd.plist” entry is created. This copied binary is then launched as follows
sh -c “launchctl submit -l ‘questd’ -p ‘/Users/mr.x/Library/AppQuest/com.apple.questd’
Launchctl uses launchd to create system-wide daemons or user specific agents; they are part of the launchcd system in Mac. The ‘submit -l’ parameter can initiate a program (whose path is mentioned after -p) with the given label, in our case ‘questd’; it is this component that initiates the encryption of the user’s files.
Once the encryption is complete, the legitimate binary that was appended is copied as a separate hidden file, retaining the same name, and is then executed using the _exec command with executable attributes conferred using _chmod as shown in Figure 17.
As always, stay protected with a best in class security product like “K7 AntiVirus for Mac.” And of course, steer well clear of pirated software.
K7 AntiVirus detects this malware as Trojan ( 3ac070911 ).
Indicators of Compromise (IoCs)