|

New malicious packages in PyPI: What it means for securing open source repositories

Karlo Zanki
Blog Author

Karlo Zanki, Reverse Engineer at ReversingLabs. Read More...

pypi-poisoned-packages
After a recent discovery of malicious PyPI packages, questions remain about the security community’s ability to mitigate threats posed to open source repositories.

The threat of software supply chain attacks has taken center stage in the year 2022, and a robust track record of these attacks demonstrates that there is an evergreen threat to software at large. What put software supply chain attacks on the map was SolarWinds. But more recently, the dangers associated with the use of open source repositories specifically has made itself more clear in the newer software supply chain attacks that are unfolding. 

The recent IconBurst software supply chain attack, discovered by ReversingLabs, is a perfect example of how open source repositories can unfortunately be abused by malicious actors. What we found was a widespread campaign to install malicious NPM modules capable of harvesting sensitive data from forms embedded in mobile applications and websites. Unfortunately, IconBurst is just one example of public repositories being the attack vector for threat actors. 

This week, a new attack on open source unfolded. ReversingLabs’ Robert Perica and I detected several new malicious packages in the PyPI public repository, uploaded by a separate author. Perica believes that the packages found are almost identical, differing mainly by their names. The basic functionality of these packages is also identical, in that they beacon back successful installation to the C2 server and download a stage 2 payload from the remote server. This payload can be detected by using the open source YARA rule for Parallax RAT.

The following code snippet is of the first malware stage, within the published PyPi package, that downloads the Parallax RAT executable with the file extension reserved for screensavers on Windows.

 

Figure 1: Python code responsible for communication with C2 server 

Figure 2: One of two user accounts used for publishing of malicious packages 

ReversingLabs reached out to PyPI’s security team about these malicious packages, and they responded soon after saying that they had removed all of the packages as of August 23rd, 2022.   

Malicious packages found on public repositories like PyPI are not a new threat, being similar to IconBurst and other supply chain attacks abusing open source software. However, what is truly alarming for the security community are the recent attacks that have been performed by automatic submission of a large number of malicious packages to open source repositories. For example, on August 19th 2022, more than 900 malicious NPM packages were submitted by a single user, demonstrating that the mass volume of these malicious packages and the abilities of threat actors to easily dump them in public repositories is a current reality. 

Figure 3: User account used for publishing of malicious npm packages

With the increasing amount of malicious packages popping up in open source repositories, the bandwidth of the security community may not be prepared to prevent open source-based software supply chain attacks from occurring. Currently, open source software libraries and components form the foundation of, by some estimates, 75% of applications. With an increasing reliance on open source packages, the attacks on these repositories has increased as well: attacks on npm and PyPI combined have surged 289% since 2018

The spreading of malicious packages is now not the only threat to public repositories. Today, PyPI shared on Twitter (see below) that they have received reports of a phishing campaign targeting PyPI users. They stated that this is the first known phishing campaign against PyPI, creating another realistic threat impacting open source repositories.  

 

While it’s clear that open source repositories enable thriving developer communities, security researchers still stand alone in detecting and mitigating these kinds of threats, since public source repositories like PyPI and npm struggle to prevent them, while at the same time never-before-seen threats are emerging. 

To learn more about the technical details of this new attack, its indicators of compromise (IoCs), and best practices for avoiding and mitigating these kinds of attacks, continue reading. 

Anatomy of the attack

As a part of this malicious campaign almost 40 PyPI packages were published to the PyPI repository from two different accounts — pypzz and pypiappz. Since all of the packages contain almost identical code shown in Figure 1, it can safely be concluded that the same actor is managing both of them. All of the packages from the same author were published in a very short period of time leading to a conclusion that some kind of automated publishing process was utilized. 

As described earlier, the functionality of these python packages is quite simple. First they beacon back to the C2 server notifying it about successful installation. After that stage2 payload is downloaded and executed on the infected machine. Download link for the stage 2 payload is hxxps://python-release.com/python-install.scr. The domain as well as package names lead to the conclusion that the malicious actor is trying to impersonate the legitimate python download website.

Figure 4: Impersonation attempt of the legitimate python download webpage

Looking at the content of the webpage hosted on this impersonation domain shows a slightly corrupt web layout. What stands out is a notice at the top of the page trying to convince the visitor into enabling javascript execution on this webpage. HTML source code of the page references a suspicious script. 

Figure 5: Reference to a suspicious jquery script

The name tries to mimic a jquery javascript file, but the content of the script is obfuscated with Javascript obfuscator (mentioned in a few of our previous blog posts). The contents of this script uncover another file hosted on this weblocation which can also be downloaded under the name python-setup.zip.   

Figure 6: Artifacts revealing usage of Javascript obfuscator 

So to quickly summarize, the python-release.com domain hosts two downloadable files python-install.scr and python-setup.zip. The first one, referenced directly from PyPI packages, contains packed Parallax RAT malware. The second one is a zip archive containing several legitimate executables signed by Python Software Foundation. But it also contains an executable named python-install.scr (the same name as the one referenced from the PyPI packages) signed with a certificate issued to M-Trans Maciej Caban organization. 

Figure 7: Valid signature of the malicious executable 

The signature is valid but the file contains malicious .NET executable in the file overlay. Behavior indicators extracted from this .NET executable reveal that it performs credential stealing from Microsoft Edge and Google Chrome local databases and exfiltrates that data to python-release.com C2 domain.

 

Figure 8: Behavior indicators extracted from python-install.scr payload

One of the powerful features ReversingLabs a1000 platform provides is URL analysis. It provides a way to see a history of analysis performed for some domain and to see how many different files were downloaded from that domain. In this case 4 different files were downloaded from this domain and so far, only two were covered with the current research. So it is possible that earlier in time, different files were served when the same URL was visited.

Figure 9: Behavior indicators extracted from python-install.scr payload

ReversingLabs file similarity algorithms confirm this information and enable pivoting from the original two samples to the other ones previously hosted on the same domain. One of the files discovered in this way exfiltrates data to linkedopports.com domain, which is also seen in the PyPI packages as the domain to which beaconing about successful malware installation is reported. Both of the domains have alexander surovcev under their Registrant Organization entry in their public domain record. The total list of malicious files discovered during this investigation can be found in the IoC section at the end of this blog post.   

Indicators of Compromise (IoC)

C2 domains extracted from the analyzed PyPI packages:

linkedopports.com

python-release.com

Stage 2 payloads:

b33824cafd32e7fb1a7bf01865ddac69f1ffd038

68d32e3b84c0596805f438fb1cfc1b3befba821f

1e697bc7d6a9762bfec958ee278510583039579c

567e1d5aa3a409a910631e109263d718ebd60506

0a6731eba992c490d85d7a464fded2379996d77c

d3ed1c7c0496311bb7d1695331dc8d3934fbc8ec

a30df748d43fbb0b656b6898dd6957c686e50a66

Package versions:

statmodel

4.5.2

204914fd686aeea8dfe6b2cdb740b394e94488e3

etuptool

4.4.9

3aa184781b0a047b6a9a68cdd6a6b09de16b4f3f

yinance

4.5.2

2aaa80ce453a35728241193feae0dee707ae366f

yaudio

4.5.2

98629ee071cced65aef699ace70a2aef2a84d444

proxycrape

4.5.2

e2386d874347cf15771b9aa42ae97b7e27b44434

etuptool

4.5.2

e66e558d8d6187c9fd12e585ee73ff22e3f9d80f

etuptool

4.4.8

ac152bffd1f6c35467c3aef0b00ef4c4ba1a9978

deeepl

4.5.2

ca39a7a5ceee86a1ce1fd13463138385d8364c82

statsmodel

4.5.2

2b29eeb77e5a0fdc78cf5a50365824d435121b6d

proxyrape

4.5.2

700e8b533406bbe2a4934c4a5ba1f312b4be8fac

yinstaller

4.5.2

1a9f683a47d242c2aba4a4c811ab0ffc9a062e34

etuptool

4.4.7

cc1bcf24e17957dfa533aaa951d823370adf0cf3

etuptool

4.5.1

1f7549003aa8cd96682962effcad48005ff31366

eepl

4.5.2

f51fb81df3dc990b91c11afe59117487d1847056

ywin32

4.5.2

4b768ac033b2bc673038f10ed7106a9ede01447d

statmodels

4.5.2

b2467b8689232ca2e3d14f078c1b242f2c389435

discordhook

4.5.2

1e44d0184dc43714cf78394a33ba121717c3e5dc

igtoolz

4.5.2

86a50659bbde4310afef05b94a8e8db14e06f8e5

elenium

4.5.2

3f336b5768b015c4dd7d2ad10c4a132187b6f812

asn2crypto

4.5.2

801fbbacf11f0ba4f36964408d37bbaa6d86616e

bitcoinliv

4.5.2

5f2821f973045bde351254bb5b3612428e90767e

crypto-data-fetch

4.5.2

0abc9b6b0bec33be282f3abd93be79a339ea333e

crypto-get-price

4.5.2

0ae235914da06b39dc6fa8e6d9a97eae92d679f1

crypto-open

4.5.2

024dfa015eca044014800c4fa95fae549f5bdf14

crypto-os

4.5.2

ec1da8be4029d12688e934b8a901867cff0f3395

cryptobalance

4.5.2

5bce39d594b360a044586f7b271000788c1ec6c8

django-metamaks-auth

4.5.2

20379bac52e98d84dca01e29e407013dd25af038

django-metamask-aut

4.5.2

e064a11c1890f7c059e98411b854236d1869b99f

django-web2-auth

4.5.2

c1424d23a3b60b80103a87dea831641c861b59b3

django-web3-aut

4.5.2

d2b8a49e615597e4b0eaf0a833371d881803464c

django-web4-auth

4.5.2

cd52dc473a8207546bae0d76c93c7def3cc2e775

hameni

4.5.2

27473d1193e4ab1bded44119b0f7ed95fb81b062

historic-crypt

4.5.2

c7ad5141df48d63f7264388176bce1fd6f828984

jango-metamask-auth

4.5.2

c7a103b612ed783fd5bbc252681130d711cb5189

jango-web3-auth

4.5.2

5130d078b886488f252399121cfeb6f442582fed

pyvrypto

4.5.2

29b6a61addbc465c0f3ae9a1dc32654a9adcced7

pyxrypto

4.5.2

16719ab5dbf1d4ca7661f3518257cd1019de540e

ycrypto

4.5.2

0de72b64d5da5b93c9b45b89d98fd4d9cd8d19f0

ycryptodome

4.5.2

e467fa8c098cc4c360571b1532e2da21e8b1702d