|

SentinelSneak: Malicious PyPI module poses as security SDK

Karlo Zanki
Blog Author

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

SentinelSneak2

A malicious Python file found on the PyPI repository adds backdoor and data exfiltration features to what appears to be a legitimate SDK client from SentinelOne.

A malicious Python package is posing as a software development kit (SDK) for the security firm SentinelOne, researchers at ReversingLabs discovered. The package, SentinelOne has no connection to the noted threat detection firm of the same name and was first uploaded to PyPI, the Python Package Index, on Dec 11, 2022. It has been updated 20 times since, with the most recent version, 1.2.1, uploaded on Dec 13, 2022. 

The package appears to be a fully functional SentinelOne client, but contains a malicious backdoor, according to ReversingLabs threat researcher Karlo Zanki. The malicious functionality in the library does not execute upon installation, but waits to be called on programmatically before activating - a possible effort to avoid detection. We are calling this campaign "SentinelSneak."

The SentinelOne imposter package is just the latest threat to leverage the PyPI repository and underscores the growing threat to software supply chains, as malicious actors use strategies like “typosquatting” to exploit developer confusion and push malicious code into development pipelines and legitimate applications.

Background

The ReversingLabs research team is continuously monitoring open-source package repositories for instances of malicious code and software supply chain attacks. This work involves both automated and human-led scanning and analysis of packages published in the most popular public package repositories like NPM, PyPI, Ruby and NuGet. 

During these scans, we leverage our proprietary Titanium platform, and our deep file repository of goodware and badware to spot malicious and even suspicious elements hiding in plain view. Our ReversingLabs secure.software solution builds upon that past work. The platform provides a way for dev and SOC teams to deeply examine their CI/CD workflows, containers and release packages to spot nascent or active software supply chain compromises.

Frequently, our work turns up evidence of active software supply chain attacks. In April, for example, we came across NPM packages that used a javascript obfuscator to hide their functionality. Our analysis of those packages produced proof of simulated “dependency confusion” attacks on the software supply chain of leading German companies across a number of industries. (That campaign turned out to be the product of an authorized “red team” exercise conducted by a security firm on behalf of its customers.)

In July, a similar inquiry uncovered a wide ranging campaign on the npm platform we dubbed “IconBurst.” That campaign employed a technique known as “typosquatting,” with many of the malicious packages using naming that was similar to popular npm packages offering icons for use in graphical interfaces. We wrote about another typosquatting campaign dubbed “Material Tailwind” in September, also on the npm platform. That included a malicious npm package masquerading as a development tool for Tailwind CSS and Material Design, two popular npm packages. That malicious package included a post-install script that downloaded a malicious executable capable of running PowerShell scripts on systems that installed the Material Tailwind package.  

PyPI saw less malicious activity relative to npm. In fact, our State of Software Supply Chain Security report found that, in contrast to npm, the PyPI repository saw a nearly 60% decrease in malicious package uploads this year, going from 3,685 in 2021 to 1,493 packages through the first 10 months of 2022. But malicious PyPI activity since 2020 is still way up (there were just eight malicious packages detected in 2020). And recent weeks have seen a number of malicious campaigns on PyPI, including a campaign of malicious packages distributing the W4SP stealer malware. 

We are continually tracking PyPI repositories for suspicious behaviors. And those efforts led to the discovery of our most recent malicious package, which attempts to hijack the name of a respected cybersecurity firm, SentinelOne.

Discussion

The core capability of ReversingLabs’ secure.software solution is analyzing code intent while highlighting malicious behaviors. These indicators cover all kinds of software behavior, from network and file system activities to use of packers associated with malicious campaigns, and the use of evasion techniques.

Red flags in allegedly ‘commercial’ module

In the case of the SentinelOne PyPI package, our researchers were tipped off by telltale suspicious behavior including the execution of a file, the spawning of new processes and the presence of URLs that reference a host by IP address. 

PyPI package without description is always suspicious   

Figure 1: PyPI package without description is always suspicious

Even a cursory glance at the SentinelOne PyPI package raises red flags. The project page has a very rudimentary look with no description of the SentinelOne package and a maintainer account that was created only days before the initial package was uploaded. While such behaviors are sometimes observed in legitimate modules, this is not behavior that would be expected from a commercial software vendor of SentinelOne’s stature. 

Taking a look at the SDLC (software development lifecycle) report generated with ReversingLabs secure.software platform provides clues that helped to quickly pinpoint the location of the malicious content in the counterfeit SentinelOne package. In the following sections, we'll discuss that in more detail.

Why SentinelOne? 

The most obvious point is that the SentinelOne PyPI package we discovered has no connection to SentinelOne, the respected cybersecurity firm that offers threat detection and response capabilities. It appears that the malicious actor(s) behind the SentinelOne PyPi package are attempting to draft on SentinelOne’s strong brand recognition and reputation. The malicious PyPI package poses as an SDK that will abstract access to SentinelOne’s APIs and make programmatic consumption of the APIs more simple.

Funky functionality

The first clue that something was amiss with the SentinelOne PyPI package was that most of the “interesting” behaviors detected by TitaniumPlatform were concentrated in just two api.py files, out of more than 100 code files in the project. Especially interesting was the combination of the detected behaviors which includes enumeration of files in a given directory, deleting of a file/directory and creation of a new process. When such behaviors are combined with the presence of a URL which references the host by IP address, you can mark that module as suspicious. Referencing the host by an official domain would be expected from a commercial product.  

Interesting behavior indicators triggered on


Figure 2: Interesting behavior indicators triggered on
api.py files

That sense was confirmed when we compared the differences between roughly 20 versions of the SentinelOne PyPI package uploaded over the course of two days. Only one python source code file changed between the versions out of the scores of files that make up the package. Which package? You guessed it: api.py.

Data exfiltration URL from


Figure 3: Data exfiltration URL from
api.py files

The second “red flag” was the discovery of networking strings in the code of the two api.py files. As mentioned earlier, one of the things that triggered our threat detection heuristics was the presence of URLs that reference the host by an IP address that was not affiliated with the company SentinelOne.

Behavior differences between two of the package versions


Figure 4: Behavior differences between two of the package versions

The api.py files were also where we located the malicious code. A detailed analysis of that code revealed capabilities that are focused on exfiltration of data that is characteristic for development environments. 

Data exfiltration


Figure 5: Data exfiltration

In the above screen grab, for example, we see the malicious code for collecting information about shell command execution history as well as the contents of the .ssh folder containing ssh keys and configuration information, including access credentials and secrets, related to git, kubernetes and AWS services. 

The code likewise performs a directory listing of the root directory. The collected data is then exfiltrated to the command and control (C2) server. Though clearly malicious, the counterfeit SentinelOne package is selective: taking only what is needed, and focusing on the subset of services that are found on machines used for software development. 

Anomalies in module naming


Figure 6: Anomalies in module naming

Further analysis of the changes between the versions of the counterfeit SentinelOne module shows that the attacker modified its functionality to adapt to targets. For example, initial versions of the module didn’t make any distinction based on the operating system in which they were executed. But it seems that version of the data collection algorithm didn't work correctly if it was executed in the Linux environment, based on hardcoded paths to targeted directories. Those issues were fixed in later versions and the malware’s data stealing capabilities were expanded with subsequent releases.

Adapting malicious code based on host environment


Figure 7: Adapting malicious code based on host environment

During development, the malicious actor published five additional packages with similar naming variations, which were used for testing purposes and did not contain api.py files with malicious functionality. These packages were published between December 8th and 11th, 2022. ReversingLabs reported the incident to the PyPI security team on December 15th, 2022, and SentinelOne was notified on December 16th, 2022. 

IOCs

Data exfiltration IP address:

54.254.189.27

PyPI packages:

 

package_name

version

SHA1

SentinelOne

1.0.0

68b09896b65db21d2c6cd2923d2486a2f69f73ef

SentinelOne

1.0.0

557af28f0a42d4fb7466376ce422bcb518e7ccc0

SentinelOne

1.0.1

1378d35524804d2f0e42fc1e8e6365211713731f

SentinelOne

1.0.1

3859aa3ddc941be0d8459b90244f7cb0f48da1be

SentinelOne

1.0.2

268546ab1aedee336151933159f056c45844ef4c

SentinelOne

1.0.2

3eaa0ced4d19742c35bc3d9a99636e5333ceb573

SentinelOne

1.0.3

94f6ba66169f54975771d6201bd8a40a65ffee16

SentinelOne

1.0.3

9e0373a8e50a1a87a552cd25cfdad51322b00719

SentinelOne

1.0.4

3c4d2e0f3125817c10ae4aa4a29a8ddcedbe3065

SentinelOne

1.0.4

f8438699804645ebc7cc573cc1326050814b02e4

SentinelOne

1.0.5

661450bd7934ae7a138a040d9d27b086414237d3

SentinelOne

1.0.5

de2a6dfbed323e0109ce02737df1d9ce5de38561

SentinelOne

1.0.6

1a891771806974ec18111a6c69b6d5bb92d6298d

SentinelOne

1.0.6

a219cec2f4a3ea2c2a707925473ebe68b620e75c

SentinelOne

1.0.7

596659f434ef78a4f7433c59d3efa79d50fa3de2

SentinelOne

1.0.7

d932be913409595ecc1d94e644c5050f5d5ce5a3

SentinelOne

1.0.8

8d02c52b03b034774bfb6767d53569035aa6398b

SentinelOne

1.0.8

52bf75dc7db3db210eea58bcea31d6cf7964a5d1

SentinelOne

1.0.9

1ee6eace8ccf865fc4ddb67d895833ad664f7a5b

SentinelOne

1.0.9

d394756d77d2cd85fce527c3cd3c1e4c7ebdd1fb

SentinelOne

1.1.0

b4a490e54f9ed0f584de48dad80cc35217fa528d

SentinelOne

1.1.0

0b25161aa8a4e0ea3be8ad8870409e4c93941086

SentinelOne

1.1.2

19a6b849d6bcb7a8dbbbde2158923135c0ee647c

SentinelOne

1.1.2

508a81ffe18fd608fddcb73ea2aba4a83c1a8fc3

SentinelOne

1.1.3

12ea7268665ea0e2688a47278c6b24ea6f907535

SentinelOne

1.1.3

ed5433e5c3b836ee9a4f9f3dde6c8b4e703eca0e

SentinelOne

1.1.4

9673c811de0ab875b542eaabfed121100f3ffad9

SentinelOne

1.1.4

1dca0855dd4175dadbe2f9917ad4e1ab176c8052

SentinelOne

1.1.5

7298b2bbf8558259ed8a5f2a286e1c2607e85bd5

SentinelOne

1.1.5

3bd886c69d380745a2db2a2da3b8d9adbff4627e

SentinelOne

1.1.6

c5af9a6308e4720a451f79124ee238ce8e021087

SentinelOne

1.1.6

43d2dbe829300587d5672c9209c39233a0d1ff8d

SentinelOne

1.1.7

37407dbd8f41a896ce8c68bc2eb5a7041e9fe47d

SentinelOne

1.1.7

b3a35866f23496cf52b8c7ad609f64b39003a386

SentinelOne

1.1.8

5ac10152a5db8b5f3ca827616a526314ad9b8983

SentinelOne

1.1.8

3f62cd17186dd821495080b7fed822ad271b9a24

SentinelOne

1.1.9

ca3aecd84b5b82ee0dac98223111bf300fec6441

SentinelOne

1.1.9

2ee8cec7f388873ad50c6108e16225b344035e4c

SentinelOne

1.2.0

1a16d6cacd5cd19b143d88f6f93cb15b535e8f15

SentinelOne

1.2.0

9ba06781f172dd8a0bfd333c6f18ea7b15af3d85

SentinelOne

1.2.1

761cfd2c1c38477ff27291b841f27c345622d58f

SentinelOne

1.2.1

adc917741164cc59da629cc4fd44f9f46ec06a2d

sentinelone-sdk

6.2.2

085b0b8974a8d93998a2dafb1335306b676274eb

SentineloneSDK

1.0.0

48fda8ccdf50e7c210c3cffe1af3572b1962bd68

Sentinelone

1.0.0

e4f6c8886de708a4c16e88e3ebf17f60adfacbad

SentinelOneSDK

1.0.0

5d843c53ef47ef89a1ab4a8d2e58bb9c2ae6bf34

sentinelone-sdk

6.2.1

bc890c4578ba52a27902c4b6e2bfe0c18ca84a2d

 

SSL certificate:

A self-signed SSL certificate was associated with the 54.254.189.27 IP address. Since the data exfiltration uses https protocol and there is a high correlation between the certificate issue and package publishing dates, it is very likely that the certificate is related to this campaign.

 

SHA1

2a12e17eff9a485f03dc707a6be76ecb23aded7e

Serial number

110586408742899611342786376272762984188488572179

Subject

Internet Widgits Pty Ltd (default value for this field)

Issued

2022-12-11

Expires

2023-12-11

 

Conclusion

The SentinelOne PyPI package is a malicious module that attempts to exploit the name and reputation of the cybersecurity firm SentinelOne. The module appears to have been built on top of legitimate SentinelOne SDK client code, likely obtained from the company by way of a legitimate customer account. 

It contains a backdoor as well as information stealing capabilities. The malicious functionality was placed in the package through the addition of two Python modules, both api.py files. The malicious code appears designed to siphon sensitive information from development environments, according to an analysis by ReversingLabs.

Based on our analysis of the malware and the associated C2 infrastructure, it is unclear if this package was or is being used in active attacks against development environments. We found no evidence of such attacks. However, download statistics from PyPi suggest that the package was downloaded more than 1,000 times. ReversingLabs notified PyPI and SentinelOne about our discovery and the presence of this malicious package in the PyPI repository. 

This latest discovery underscores the ongoing threat of malicious code lurking on open source repositories such as PyPI, npm, RubyGems, GitHub and more. As with prior malicious open source supply chain campaigns, this one attempts to exploit confusion on the part of developers to push malicious code into development pipelines. In this case, the attackers attempt to leverage the name and reputation of SentinelOne, a highly respected cybersecurity firm, to fool users into downloading a malicious payload that includes a backdoor. 

Also like prior incidents, this discovery shows telltale signs of malicious activity, including the execution of a file and use of URLs in the code that reference a host by IP address, rather than a DNS host name. 

Though small in scope, this campaign is a reminder to development organizations of the persistence of software supply chain threats. As with previous malicious campaigns, the "SentinelSneak" campaign plays on tried and true social engineering tactics to confuse and mislead developers into downloading a malicious module. To counter such attacks, development organizations need to invest more heavily in training and awareness campaigns that ensure developers will not fall for typosquatting and other impersonation attacks. It also highlights the need for tools and processes to ensure that any open source or proprietary code is evaluated for the presence of suspicious or malicious indicators including hidden (obfuscated) functionality, unexplained communications with third party infrastructure and more.