Sonatype has discovered 'pytoileur', a malicious PyPI package hiding code that downloads and installs trojanized Windows binaries capable of surveillance, achieving persistence, and crypto-theft. Our discovery of the malware led us to probe into similar packages that are part of a wider, months-long 'Cool package' campaign.
Pytoileur: a 'Cool package'
Yesterday, our automated malware detection engines, the force behind Sonatype Repository Firewall, flagged a newly published PyPI package called "pytoileur."
Tracked as sonatype-2024-1783, the package has been downloaded 264 times since its publication yesterday and before we alerted PyPI admins to take it down. We have analyzed versions 1.0.1 and 1.0.2 of the package, both of which are identical in their functionality.
The package describes itself as a "Cool package." in its metadata, with the HTML webpage description touting it as an "API Management tool written in Python." The reference to "pystob" in the code (a now non-existent package; more on that below), is also indicative of the package attempting to typosquat users of legitimate packages like "Pyston."
PyPI user "PhilipsPY" who, at the time of writing is the author of this package (and the only package from them) had joined the PyPI platform on May 25, 2024.
Although the "setup.py" file in the package looks clean at a first glance, you'd be fooled for thinking that it's an empty package.
Sonatype security researcher and open source threat intel enthusiast Jeff Thornhill noticed that line 17 was laden with... a bit too many whitespaces — in turn hiding code much further to the right which would be easy to miss, unless you notice the scroll bar.
The command executes a base64-encoded payload:
"While the base64 encoding is pretty standard in applications and doesn't offer much in terms of masquerading malicious code, meaning in itself it's not truly "suspicious" to utilize it, the author had attempted to 'hide' this particular encoded string from manual human review by injecting it after a print statement, and then including a paragraphs' length of whitespace prior to the code," says Thornhill.
"Users viewing this in an editor without word wrap (fairly common in coding) would miss this line quite easily."
Downloads and drops a Windows binary
As for what is the base64-encoded code accomplishing? Let's take a look.
Essentially, the code is targeting Windows users and invokes Python commands to retrieve a malicious executable from an external server: hxxp://51.77.140[.]144:8086/dl/runtime
The retrieved binary, "Runtime.exe" is then run by leveraging Windows PowerShell and VBScript commands on the system.
The executable, upon installation, achieves persistence and contains several anti-detection measures to deter analysis by researchers and malware sandboxes.
The package further drops suspicious executables, modifies Windows registry settings, and deploys payload that have previously been identified as spyware.
One of the binaries ("main.exe") is seen containing info-stealing and crypto-jacking capabilities. The binary, for example, attempts to exfiltrate user profiles and data saved in common web browsers (Google Chrome, Brave, Firefox, etc.) and attempts to access llocal assets associated with fintech and crypto services like Binance, Coinbase, Exodus Wallet, PayPal, Payoneer, PaySafeCard, Crypto.com, Skrill, among others.
Abusing Stack Overflow to entice victims
We further noticed that a Stack Overflow account "EstAYA G" created roughly two days ago is now exploiting the platform's community members seeking debugging help [1, 2, 3] by directing them to install this malicious package as a "solution" to their issue even though the "solution" is unrelated to the questions posted by developers.
We can only hope developers will use their best judgment and not fall for this trap.
Part of the wider 'Cool package' campaign
Upon digging deeper into the structure of "Pytoileur," its authorship history, and its association with the "pystob" (malicious) package which was also previously identified by Sonatype and removed from the PyPI registry, we deem this package a part of the wider attack campaign from last year which has effectively been revived.
In 2023, a PyPI user (possibly the same one) had published several packages with the shorthand metadata description "Cool package," that employed much of the same tactics described in our finding from this week.
Many such packages also marketed themselves as an "API Management tool written in Python," or used variations of obfuscation techniques to ultimately download trojanized Windows binaries from URLs with similar structures (hxxp://51.77.xx.xx:YYYY/dl/runtime).
Additionally, packages like "gpt-requests," also associated with this campaign, would, for example, appear to target developers building AI applications (the term GPT) and describe themselves as "a simplified version of urllib," that can be used "to make your https requests." These would, however, instead contain base64-encoded payload hidden using whitespaces — just like we saw with Pytoileur.
This payload in "gpt-requests" is also achieving much the same:
Except, the second stage payload binary ("Runtime.exe") in this case was being downloaded from a now-abandoned domain hxxps://api-hw[.]com/dl/runtime.
Another cool package 'pyefflorer' associated with this campaign, employed a different form of obfuscation, to accomplish the same task:
Interestingly, it's the "lalalaopti" package though that alludes to the threat actors' real intentions behind these packages.
Published June 2023, PyPI package "lalalaopti" contained several "modules" written in plaintext Python code — as opposed to a compiled Windows binary, designed to attempt clipboard hijacking, achieving persistence, deploying keyloggers, securing remote webcam access, and taking screenshots for the attacker, among other suspicious tasks:
It isn't uncommon for threat actors to initially publish primitive versions of their malicious payload (as we see with the "lalalaopti" package) on open source registries like npm and PyPI, to test waters, before going full swing and publishing more complex packages that they can use in actual attacks.
Checkmarx researchers had previously analyzed some of these packages. We are providing a complete list of malicious packages associated with this campaign identified thus far below:
gogogolokl
gpt-requests
kokokoako
lalalaopti
pybowl
pyclack
pyefflorer
pyhjdddo
pyhulul
pyioapso
pyjio
pyjoul
pykokalalz
pykooler
pyktrkatoo
pylioner
pyminor
pyowler
pypiele
pystallerer
pystob
pytarlooko
pytasler
pytoileur
pywolle
pywool
This week's reemergence of an identical malicious Python package is a testament to threat actors reviving and recycling old tactics to cast their net wider and expand their set of targets, who often involve developers of several niches (i.e., from AI and machine learning enthusiasts to those relying on popular Python frameworks like Pyston).
Users of Sonatype Repository Firewall are protected from counterfeit components like these, which would be blocked from entering their builds. We may discretionarily expand our blocklists periodically as similar packages surface and our investigation into this campaign progresses. If you're not already protected with Sonatype, get in touch so we can show you Firewall in action.
Written by Ax Sharma
Ax is a Staff Security Researcher & Malware Analyst at Sonatype with a penchant for open source software. His works and expert analyses have frequently been featured by leading media outlets including the BBC. Ax's expertise lies in security vulnerability research, reverse engineering, and cybercrime investigations. He has a passion for educating a wide range of audiences through writing and vlogs.
Explore All Posts by Ax Sharma