Keypoints
- Researchers identified 116 malicious files spread across 53 PyPI projects, with over 10,000 downloads total.
- Operators used three packaging techniques: malicious test.py modules, PowerShell embedded in setup.py, and packages containing only obfuscated malicious code.
- pip’s preference for wheels over source packages allowed built (malicious) wheels to be installed even when source looked clean.
- Windows persistence used encoded VBScript files and scheduled tasks; Linux persistence used XDG autostart desktop entries executing downloaded binaries.
- Final payloads included a Python backdoor (Windows), a Go backdoor (Linux), W4SP Stealer variants, and clipboard monitors that replace cryptocurrency addresses.
- Command-and-control used an unencrypted custom TCP protocol (example C2: blazywound.ignorelist[.]com on port 6001) and next-stage payloads were hosted on transfer.sh and Dropbox.
- Most malicious packages were removed from PyPI after ESET reported the activity; full package list published on GitHub.
MITRE Techniques
- [T1195.001] Supply Chain Compromise: Compromise Software Dependencies and Development Tools – Malware is distributed using Python’s PyPl package management service. ‘Malware is distributed using Python’s PyPl package management service.’
- [T1053.005] Scheduled Task/Job: Scheduled Task – On Windows, persistence is achieved using a scheduled task. ‘On Windows, persistence is achieved using a scheduled task.’
- [T1547.013] Boot or Logon Autostart Execution: XDG Autostart Entries – On Linux, an autostart entry is created to launch the backdoor when the user logs in. ‘On Linux, an autostart entry is created to launch the backdoor when the user logs in.’
- [T1036.005] Masquerading: Match Legitimate Name or Location – On Linux, persistent files have names similar to legitimate software. ‘On Linux, persistent files have names similar to legitimate software’
- [T1555.003] Credentials from Password Stores: Credentials from Web Browsers – W4SP steals passwords from the installed web browsers. ‘W4SP steals passwords from the installed web browsers.’
- [T1115] Clipboard Data – To steal funds during a cryptocurrency transaction, clipboard data is replaced. ‘To steal funds during a cryptocurrency transaction, clipboard data is replaced.’
- [T1095] Non-Application Layer Protocol – The backdoor uses an unencrypted binary protocol over TCP. ‘The backdoor uses an unencrypted binary protocol over TCP.’
Indicators of Compromise
- [SHA-1 hashes] File samples – 439A5F553E4EE15EDCA1CFB77B96B02C77C5C388 (cache.py), B94E493579CC1B7864C70FAFB43E15D2ED14A16B (coloramma-0.5.4-py3-none-any.whl), and 5 more hashes.
- [Filenames & paths] Persistence and payload files – %APPDATA%/Pythonenv/pythenenv.vbe, ~/.config/autostart/mate-user-share.desktop.
- [Domains/IPs] C2 and hosts – blazywound.ignorelist[.]com (204.152.203[.]78) used as C2 on port 6001.
- [URLs] Download locations for next stages – transfer[.]sh/eyRyPT/Updater.zip, dl.dropbox[.]com/s/u3yn2g7rewly4nc/proclean.
- [Package names] Malicious PyPI packages/projects – coloramma, proclean, and 51 other project names (total 53 projects containing malware).
The operators bundled malicious code into PyPI packages using three main techniques: (1) embedding a lightly obfuscated test.py module imported by the package’s main module so malicious code executes on import, (2) placing PowerShell installers inside setup.py to download and run a ZIP payload (e.g., transfer[.]sh/…/Updater.zip → C:ProgramData → pip install dependencies → run server.pyw), and (3) publishing packages that contain only obfuscated malicious scripts which write temporary files and launch them with pythonw.exe to avoid a console window. Attackers leveraged pip’s preference for wheels so a malicious built distribution could differ from a clean source distribution and be installed automatically.
For persistence and execution, Windows installs an encoded VBScript (VBE) to %APPDATA%/Pythonenv/pythenenv.vbe, hides the directory, executes the VBE, and schedules it to run every five minutes under a task (MicrosoftWinRaRUtilityTaskB). On Linux, the packages drop a deceptive desktop entry (mate-user-share.desktop) into ~/.config/autostart/ that launches a downloaded executable placed under ~/.config/.kde/.kdepath, impersonating a configuration path to reduce suspicion.
The typical final payload is a remote backdoor (Python on Windows, Go on Linux) that opens a TCP connection to a C2 (example: blazywound.ignorelist[.]com:6001), sends host identifiers (hostname, MAC, username), and accepts remote commands or spawns processes to return output. Variants also include W4SP Stealer (browser password theft) and simple clipboard monitors that use the pyperclip library to detect cryptocurrency wallet addresses and replace them with attacker-controlled addresses. Next-stage binaries and scripts were hosted on transfer.sh and Dropbox; most malicious packages were removed from PyPI following disclosure.
Read more: https://www.welivesecurity.com/en/eset-research/pernicious-potpourri-python-packages-pypi/