Attacker targeting Python developers 

Key Points 

  • For nearly half a year, a threat actor has been planting malicious Python packages into the open-source repository. 
  • Many of the malicious packages were camouflaged with names closely resembling popular legitimate Python packages. Consequently, they received thousands of downloads. 
  • The setup.py file within these packages was used to carry the harmful payload, which allowed the malicious code to be executed upon installation. 
  • A defining characteristic of this attack was the utilization of steganography to hide a malicious payload within an innocent-looking image file, which increased the stealthiness of the attack. 
  • The attack pattern pointed to a systematic approach, with the code in these packages exhibiting similar obfuscation techniques and harmful payloads. 
  • The ultimate goal of these packages appears to be gaining persistence on the compromised systems, stealing sensitive information, and achieving financial gains. 

It has become commonplace for attackers to invest a significant amount of time and effort within the open-source ecosystem.  

Attackers, driven by malicious intent, demonstrate an extraordinary level of persistence in their pursuit of exploiting vulnerabilities in the open-source ecosystem. While they may not always achieve their objectives in every single attack, their unwavering determination allows them to eventually identify and target vulnerable individuals or organizations. This persistence, coupled with the increasing number of attackers engaging in these activities, suggests that there is a certain degree of success within this realm. 

For close to six months, a malicious actor has been stealthily uploading dozens of malicious Python packages, most of them mimicking the names of legitimate ones, to bait unsuspecting developers. 

All packages containing malicious code had it embedded within the setup.py file, allowing the code to execute upon package installation. For packages that didn’t directly contain malicious code, they included references to other malicious packages, likely to trick developers into downloading them. These malicious packages contained different variations of malicious code, but the most common method of operation was as follows: 

  • User Identification: The scripts began by verifying the username of the logged-in user. 
  • Directory Verification and Creation: They checked for a particular directory named “System64” within the user’s Start Menu Programs path. If nonexistent, the script created it. 
  • File Placement and Execution: The scripts then deployed VBScript and batch files that downloaded and executed a file named “Runtime.exe”, ensuring its persistence on the system by placing it in the system’s Startup folder. 
  • Stealth and Cleanup: Post-execution, the scripts cleared their tracks by deleting the evidence of their presence. 

A Common Blueprint 

The initial obfuscated code within the setup.py file followed a similar structure across most packages: 

Upon deobfuscation, the script’s true nature was revealed, with minor variations distinguishing one malicious package from the other: 

The “Runtime.exe” turned out to be a Python program harboring a compiled file “s.pyc”. From this, we extracted disassembly code that was designed to steal extensive sensitive information from the compromised system, various browsers, and applications. 

Financial Data Theft 

Like many attacks we’ve increasingly seen during these past couple of years on the open-source ecosystem, the attacker in this case seemed to also aim to profit from cryptocurrency. The script demonstrates its capability for stealing financial data, with a specific focus on targeting cryptocurrency assets. It would scan for the ‘Local State’ file of the Exodus cryptocurrency wallet, which usually includes sensitive configuration data that could be exploited to gain unauthorized access to a user’s cryptocurrency funds. 

Exfiltration 

The stolen information is ultimately stored in separate files named: 

  • alls.armageddon 
  • ckk.armageddon 
  • imp.armageddon 
  • pskk.armageddon 
  • toks.armageddon 

These files were later exfiltrated by being uploaded to the following endpoints: “hxxp[:]//51.178.25.148:8081/uploader “ and “hxxp[:]//51.178.25.148:8081/upload”

Once this process was complete, all of these files were deleted from the host. 

Behind the Pixels: Steganography at Play 

Some outliers in this attack campaign used more sophisticated methods. They employed steganography to hide executable code within a PNG image that was downloaded from an external link and saved as “uwu.png” inside the user’s “%APPDATA%/local” directory. 

Once this was done, the image file previously downloaded was deleted, clearing its tracks. and the fetched code was decoded and executed using the built-in exec() function 

The payload was designed to collect the public IP address of the affected host and its UUID (machine ID) and exfiltrate this information to an external server.  

Encoded payload within the image: 

which translates to this: 

They all lead to two packages: 

A common thread in the descriptions of all malicious packages was the mention of “Pystob” or “Pywool”. These packages masqueraded as useful tools for API management, but upon closer inspection, were found to be obfuscated twice over, hiding their true, harmful nature. 

So, it appears as though the packages were also attempting to get their victims to deliberately download these packages. Upon investigating these two packages, it was found that their code was also placed within the setup.py file and the code was obfuscated under two layers. 

This malicious payload essentially downloads and runs executable files aimed at performing various malicious activities which also include: 

  • Collecting user data and exfiltrating it to a Discord webhook. 
  • Attempting to maintain persistence by placing a VBS file in the Windows startup folder. 

In a clever move, the attacker also utilized the domain name ‘api-hw.com’ to download the second-stage payload. This choice of domain was likely a strategic decision to make the packages appear more legitimate and relevant to their presumed functionality. However, at this time the attacker no longer has control over this domain and it appears to be available for purchase, indicating either a retreat or a shift in their strategy. 

Targets of the Attack 

One critical aspect of this attack was the selection of targets. The attackers chose popular legitimate Python packages and created malicious counterparts with similar names. This strategy aimed to increase the chances of developers accidentally downloading the malicious packages. To demonstrate the extent of this deception, refer to the table below, which compares some examples of the names of the malicious packages with their legitimate counterparts and includes the download count of the legitimate packages. Overall, the malicious packages received over four thousand downloads. 

Percentage Distribution of Total Downloads of the Malicious Package by Country 

Conclusion 

This campaign serves as another stark reminder of the ever-present threats that exist in today’s digital landscape, particularly in areas where collaboration and open exchange of code are foundational. It is crucial to recognize the importance of cybersecurity measures and remain vigilant in protecting sensitive information. 

To enhance security, consumers of open-source packages should vet packages before installing them and at the very least, utilize public advisories and security assessment platforms like the community-driven overlay browser extension. This extension provides insights into the security score and other relevant information about the package based on various platforms including socket.io, deps.dev, and snyk. By using these resources, developers can make informed decisions and reduce risks in their DevOps pipelines. 

As part of the Checkmarx Supply Chain Security solution, our research team continuously monitors suspicious activities in the open-source software ecosystem. We track and flag “signals” that may indicate foul play and promptly alert our customers to help protect them. 

Packages 

Package Name  Creation Date 
pyefflorer  5-Oct-2023 
pyhulul  3-Oct-23 
pyjio  2-Oct-23 
pyioler  30-Sep-23 
pytasler  26-Sep-23 
kokokoako  26-Sep-23 
pyalsogkert  26-Sep-23 
pyioapso  25-Sep-23 
pykokalalz  25-Sep-23 
pyhjdddo  24-Sep-23 
pyktrkatoo  23-Sep-23 
pytarlooko  23-Sep-23 
pystallerer  22-Sep-23 
pykooler  22-Sep-23 
pyowler  18-Sep-23 
pylioner  18-Sep-23 
pystob  17-Sep-23 
pyminor  20-Aug-23 
pyjoul  17-Aug-23 
pyghoster  15-Aug-23 
pypiele  30-Jul-23 
gogogolokl  6-Jun-23 
lalalaopti  6-Jun-23 
pyclack  27-May-23 
pywolle  19-May-23 
pywhool  17-May-23 
pywool  13-May-23 

IOC 

  • hxxp[:]//51.178.25.148[:]8081/upload 
  • hxxp[:]//51.178.25.148[:]8081/dl/runtime 
  • hxxp[:]//51.178.25.148[:]8081/uploader 
  • hxxp[:]//51.178.25.148[:]8081/gethw 
  • hxxp[:]//51.178.25.148[:]8081/dl/system 
  • hxxp[:]//51.178.25.148[:]8081/getip 
  • hxxp[:]//51.178.25.148[:]8081/dl/uwu 
  • hxxp[:]//51.178.25.148[:]8081/rooter 
  • hxxps[:]//pastebin.com/raw/TwHdexDC 
  • hxxps[:]//canary.discord.com/api/webhooks/1153431050517762059/MAkfrB4n1Gz6qe7W8ffWTZF92yfN3D_FWPFFaK_FBgDQWB1ZYfbKHa61X_8L6GK175r0 
  • hxxps[:]//canary.discord.com/api/webhooks/1155235432406196334/3eFtMXnG2laJjInzO_kAzLbW6ebMgbrrwmAcRtZyOfqnyCh-twTT9pSumcKr5QJvbGEZ 
  • hxxps[:]//canary.discord.com/api/webhooks/1152716297474424913/z6-hvrQNeyL0m1Mm34JLYj1VVB67sVEXogqJzGCkxYgMFCgCWhQaR07ruMBck1dJAi9g 
  • hxxp[:]//51.178.25.148[:]8081/dl/sys86 
  • hxxp[:]//51.178.25.148[:]8081/dl/gamesdk 
  • hxxps[:]//canary.discord.com/api/webhooks/1152648911371120681/JlL5FnwmY6nP6RaZxmQ7NI9MGR6HARmAekaPqPDdVTq9K3RJ68Lcd7cz16l9u6eZH9c3 
  • hxxps[:]//discord.com/api/webhooks/1103033150558457876/22oUF1rkDTdxz-iq-2EOR4aVXwDr5vFIeE9zWlitIbYSG2E3XhF8KQIzuo1uXy_bOcos 

Source: Original Post