Phylum's Monthly Malware Report: June 2022 - Don't Believe the Type
Overview
June’s Malware Analysis yielded more of what Phylum has been seeing for a while:
- NPM is targeted far more heavily than any other package registry.
- Frequent use of dependency confusion attacks.
- Frequent use of pre-install scripts to trigger malicious activity.
June Malware Analysis
Registry |
Package Name |
Package Version |
NPM ID’d |
Removed |
npm |
@byjus-orders/tyrion-plugins |
555.0.0 |
|
Y |
npm |
@cvent-wdio/testthing |
0.0.2 |
|
Y |
npm |
@cvent-wdio/testthing |
0.0.3 |
|
Y |
npm |
@cvent-wdio/testthing |
0.0.1 |
|
Y |
npm |
@cvent-wdio/wdio-configs |
0.1.17 |
|
Y |
npm |
@cvent-wdio/wdio-utils |
0.1.1-SNAPSHOT |
|
Y |
npm |
@jscad/cli |
2.2.20 |
|
|
npm |
@jscad/web |
2.5.10 |
|
|
npm |
@kraken-frontend/components |
7.0.0 |
|
Y |
npm |
@kraken-frontend/components |
5.0.0 |
|
Y |
npm |
@kraken-frontend/entry-point |
7.0.0 |
|
Y |
npm |
@kraken-frontend/eslint-config |
7.0.0 |
|
Y |
npm |
@kraken-frontend/kraken-api-client |
7.0.0 |
|
Y |
npm |
@kraken-frontend/kraken-api-clients |
5.0.0 |
|
Y |
npm |
@kraken-frontend/kraken-internal-api-client |
5.0.0 |
|
Y |
npm |
@kraken-frontend/kraken-internal-api-client |
7.0.0 |
|
Y |
npm |
@kraken-frontend/kraken-websocket-api-client |
5.0.0 |
|
Y |
npm |
@kraken-frontend/kraken-websocket-api-client |
7.0.0 |
|
Y |
npm |
@kraken-frontend/sentry |
7.0.0 |
|
Y |
npm |
@kraken-frontend/test-utils |
5.0.0 |
|
Y |
npm |
@kraken-frontend/test-utils |
7.0.0 |
|
Y |
npm |
@kraken-frontend/translations |
5.0.0 |
|
Y |
npm |
@kraken-frontend/translations |
7.0.0 |
|
Y |
npm |
@ramp106/timetable |
99.15.9 |
Y |
|
npm |
@ramp106/timetable |
99.16.9 |
Y |
|
npm |
@ramp106/timetable |
99.12.9 |
Y |
|
npm |
@ramp106/timetable |
99.11.9 |
Y |
|
npm |
@ramp106/timetable |
99.10.9 |
Y |
|
npm |
alimaa |
2.5.18 |
Y |
|
npm |
argo-hosting-api |
3.0.0 |
Y |
|
npm |
coldstone-sls |
2.7.2 |
Y |
|
npm |
d2l-rubric |
6.0.1 |
Y |
|
npm |
d2l-rubric-polymer |
5.0.1 |
Y |
|
npm |
dragox-utilities |
1.0.2 |
Y |
|
npm |
gatsby-plugin-conecad |
1.0.0 |
Y |
|
npm |
loadah |
555.0.0 |
|
|
npm |
mdb-react-color-picker |
1.0.0 |
|
|
npm |
mdb-react-file-upload |
1.0.0 |
|
|
npm |
mmccii |
1.0.1 |
Y |
|
npm |
mohigher313 |
1.0.13 |
|
|
npm |
mohigher313 |
1.0.10 |
|
|
npm |
mohigher313 |
1.0.6 |
|
|
npm |
nexemplum |
555.0.0 |
|
|
npm |
nimble-client-js |
1.99.99 |
|
|
npm |
nimble-client-js |
5.9999.999 |
|
|
npm |
nimble-client-js |
5.2.1 |
|
|
npm |
package_test23 |
1.0.2 |
|
|
npm |
package_test23 |
1.0.3 |
|
|
npm |
package_test23 |
1.0.1 |
|
|
npm |
sorareshshsjs |
100.0.0 |
Y |
|
npm |
test-analytics-44 |
45.0.0 |
|
|
npm |
vueexxx |
1.0.3 |
|
|
npm |
wakakaa |
2.5.18 |
Y |
|
npm |
whjr-analytics |
41.0.0 |
Y |
|
npm |
whjr-analytics |
47.0.0 |
Y |
|
npm |
whjr-tech-infra |
555.0.0 |
|
|
npm |
xiawaa |
2.5.18 |
Y |
|
npm |
yadanga |
2.5.18 |
Y |
|
Co-marked Malware
NPM eventually marked 19 of the 58 identified packages as malware too. It’s great to see this effort by NPM! Phylum detects malware in an average of 630-650 seconds after the package release. This is mostly because we’ve been incredibly focused on making the system as fast as humanly computably possible. I have theories about what NPM is doing to detect malicious packages, but I’ll save those for a longer blog on that topic.
Removed Packages
We noticed that 21 of the 58 identified packages were subsequently removed from NPM. This is markedly different than “malware identification” as this is an action taken by the package author.
This is a smart move by attackers. By pre-emptively removing an overtly malicious package, the author avoids detection by NPM. There are lots of reasons an attacker wants to avoid detection:
- Prevent detection of TTPs in malicious code.
- Prevent bans on author accounts.
- Test malware campaign strategies without observation.
- Definitely more I’m not thinking of right now.
Unfortunately for these attackers, Phylum stores a complete copy of every package we ingest, including metadata, source and revision history. We do this for a variety of reasons, but this is a notable example of where it is useful.
Registry |
Package Name |
Package Version |
npm |
@cvent-wdio/testthing |
0.0.2 |
npm |
@kraken-frontend/sentry |
7.0.0 |
npm |
@kraken-frontend/kraken-internal-api-client |
5.0.0 |
npm |
@kraken-frontend/kraken-internal-api-client |
7.0.0 |
npm |
@kraken-frontend/components |
5.0.0 |
npm |
@kraken-frontend/test-utils |
5.0.0 |
npm |
@byjus-orders/tyrion-plugins |
555.0.0 |
npm |
@kraken-frontend/kraken-api-clients |
5.0.0 |
npm |
@cvent-wdio/testthing |
0.0.3 |
npm |
@cvent-wdio/testthing |
0.0.1 |
npm |
@kraken-frontend/kraken-websocket-api-client |
5.0.0 |
npm |
@kraken-frontend/kraken-websocket-api-client |
7.0.0 |
npm |
@kraken-frontend/translations |
5.0.0 |
npm |
@cvent-wdio/wdio-utils |
0.1.1-SNAPSHOT |
npm |
@kraken-frontend/kraken-api-client |
7.0.0 |
npm |
@kraken-frontend/test-utils |
7.0.0 |
npm |
@kraken-frontend/eslint-config |
7.0.0 |
npm |
@cvent-wdio/wdio-configs |
0.1.17 |
npm |
@kraken-frontend/translations |
7.0.0 |
npm |
@kraken-frontend/entry-point |
7.0.0 |
Figure 1 - Listing of author-removed malicious packages
The attackers are clearly targeting Kraken, the cryptocurrency exchange, and cvent, an event marketing company in a pseudo-typosquatting / namesquatting attack. The NPM scopes in use are not identical to the scopes used by the respective organizations, but they’re close enough that the attackers are hoping to catch a developer by mistake.
Kraken
The attacker targeting Kraken uses identical TTPs in each malicious package. In these cases, the salient part of the malicious package is merely the package.json shown below:
The attacker uses NPM’s pre-install script execution capability to exfil some host information to www.analytics-google.com/collect. I remain baffled why pre-install scripts are enabled by default.
Cvent
The attacker targeting Cvent also uses identical TTPs within the identified malicious packages. Interestingly, none of the packages include JavaScript or TypeScript source code. They are merely gzipped tarfiles with a package.json file. Packages like these are hilariously easy to identify if you ask the question “is this a legitimate software library?” The answer becomes abundantly clear if the library doesn’t include source code 😊.
Similarly, to Kraken’s case, this attacker uses NPM’s pre-install scripts to collect host information and exfiltrate it to a URL.
The exfiltration URL “*.burp.gdsburp.com” resolves to a BurpSuite Collaborator Server. These are commonly used by pentesters and security engineers to audit the security of web applications. They also function perfectly for collectors to test the results of a supply-chain attack.
Noting the package’s description of “pentest” and that the domain name “gdsburp.com” reminds me of Gotham Digital Science, a security consulting group, might suggest this is merely a package used for pentesting. But I must wonder, is this an attacker masquerading as this group? Reviewing the WHOIS and RDAP records for gdsburp.com doesn’t give me anything to assuage concerns. The overall idea drives me to another point worth discussing:
Do Not Believe Attackers
This likely goes without saying, but do not trust what attackers tell you. If we find a package that demonstrates overtly malicious behavior, we can’t put any weight into the attacker-defined text fields that accompany the package, such as the package description claiming it is a “testing” package, or that it’s for a pentest.
It would be a huge stretch to call this tradecraft, but the idea is similar. Pentesters and security engineers are going to use similar methods to actual attackers to evaluate the security posture of a system. Taken from another view, it’s a perfect place for attackers to hide the exploratory reconnaissance phase of a supply-chain attack. We simply must treat packages that exhibit malicious behavior as an attack until proven otherwise.
A Suggestion for Security Companies Testing Supply Chain Attacks
Most package registries explicitly disallow “pentest” code, but hackers gonna hack. At the very least, hang a webpage from the domain name of your collection endpoints that documents the name of the organization, a contact person, and a publicly-verifiable GPG key for inquiries. This contact person should be Internet-verifiable in some way that prevents an attacker from masquerading. I typically avoid recommending GPG keys for anything, but it should work well in this case.
PHYLUM-JUN22-ACTOR-ALPHA
An actor was identified sharing near identical TTPs dubbed “PHYLUM-JUN22-ACTORALPHA”. Demonstrative source code to the index.js source file is shown below:
The source code in index.js is nearly identical to a blog entry documenting how Dependency Confusion can be exploited.
Registry |
Package Name |
Package Version |
npm |
@ramp106/timetable |
99.15.9 |
npm |
@ramp106/timetable |
99.16.9 |
npm |
@ramp106/timetable |
99.12.9 |
npm |
@ramp106/timetable |
99.11.9 |
npm |
@ramp106/timetable |
99.10.9 |
Figure 3 - List of packages by ACTORALPHA
PHYLUM-JUN22-ACTOR-BRAVO
It was then clear to see the evolution of ACTORALPHA’s source code modified into an improved version, ACTORBRAVO.
The attacker adds a few interesting things in ACTORBRAVO:
- HTTP server listening on port 3001/tcp for command execution by querystring.
- Curl to ifconfig.me, a popular service to display the Internet-facing IP address of the host.
- Curl to a pipedream.net collector.
- Bash one-liner to create a reverse TCP shell to portmap.io.
This is overkill, clearly, but the attacker is giving themselves a lot of opportunities with these malicious packages!
Registry |
Package Name |
Package Version |
npm |
whjr-analytics |
41.0.0 |
npm |
whjr-analytics |
45.0.0 |
npm |
whjr-analytics |
47.0.0 |
Npm |
whjr-tech-infra |
555.0.0 |
npm |
loadah |
555.0.0 |
npm |
nexeplum |
555.0.0 |
npm |
@byjus-orders_tyrion-plugins |
555.0.0 |
Figure 5 - List of packages by ACTORBRAVO
Miscellaneous Bits
There were a few packages that led to a lot of head scratching. A couple bundled NetCat PE binaries but did not execute them. Another interesting package was vueexxx. This NPM package bundled a one-liner backdoor written in python, housed in a shell script, but never invoked by vueexxx or any of its dependencies.
Wrapping Up
We’re continuing to defend the open-source supply chain looking for risks beyond known vulnerabilities. I hope you enjoyed the Monthly Malware report. If you have any questions, please don’t hesitate to contact us!