Cybercriminals targeted users of packages with a total of 1.5 billion weekly downloads on npm
Table of Contents
Another week, another supply chain incident. It’s been only nine days since the Mend research team detected the dYdX incident, and today we have detected another supply chain malicious campaign.
On October 02, 2022 at 12:12 UTC, a new npm account was registered, and a package called nuiversalify was immediately uploaded. The same threat actor then proceeded to publish more typo/spellcheck squattings of popular packages until 14:03:29 UTC, with small but irregular time gaps between uploads. The irregular publishing cadence may suggest that for many name-cases, the npm typosquatting mechanism worked as expected.
In a typosquatting attack, an attacker publishes a malicious package with a similar name to a popular package, in the hope that a developer will misspell a package name and unintentionally fetch the malicious version.
In total, the threat actor published 155 packages to npm targeting users of the following packages:
Legit package name | Weekly downloads |
universality | 51,810,168 |
webidl-conversions | 61,052,599 |
shebang-command | 52,050,912 |
anymatch | 47,421,866 |
string-width | 98,034,656 |
tslib | 137,845,760 |
micromatch | 63,087,644 |
supports-color | 224,997,209 |
http-errors | 52,840,509 |
ansi-regex | 130,553,307 |
glob-parent | 68,724,436 |
ignore | 49,645,827 |
postcss-value-parser | 50,840,222 |
has-flag | 161,338,767 |
debug | 205,533,537 |
estraverse | 69,169,061 |
jsesc | 46,116,034 |
i18n | 240,385 |
Total | 1,571,302,899 |
Here are the names of the packages that were uploaded:
tsilb, nuiversalify3, micrmoatch, lgob-parent, glob-praent, http-rerors, postcss-valeu-parser, jsecs, y81n, ussports-color, stirng-width, string-wdith, webidl-conversinos, asni-regex, 1y8n, sypport-color, ahs-flag, igonre, string-iwdth, webidl-conversiosn, esrtaverse, hsa-flag, shebnag-command, webidl-covnersions, univesralify, webidl-conevrsions, strign-width, y1n8, suopport-colors, shebang-comamnd, microamtch, anymathc, uinversalify, naymatch, anis-regex, postcss-value-pasrer, ansi-reegx, webidl-convesrions, aynmatch, string-widht, wbeidl-conversions, glob-parnet, sheabng-command, ansi-rgeex, estraveres, stlib, shebang-commadn, soupports-colors, webidl-conversion, webdl-conversions, estravrese, http-erorrs, tsring-width, ignoer, has-falg, supports-colro, shebang-cmomand, deubg, shebagn-command, anmyatch, has-lfag, strnig-width, glob-aprent, opstcss-value-parser, shebang-ocmmand, supprots-color, hsebang-command, srting-width, aypports-color, estravesre, dupport-colors, nuiversalify, ansi-regxe, tlsib, spuports-color, glob-paernt, ginore, webdli-conversions, postcss-value-parsre, sehbang-command, has-flga, http-errosr, glbo-parent, golb-parent, postcss-value-paresr, string-witdh, ewbidl-conversions, universlaify, estraevrse, tslbi, suypport-colors, micormatch, thtp-errors, univeraslify, supoprts-color, ebidl-conversions, supports-cloor, anyamtch, syupport-colors, ignroe, webidl-conversoins, htpt-errors, postcss-vlaue-parser, supporst-color, postcss-value-praser, nuiversalify1, edbug, universailfy, potscss-value-parser, posctss-value-parser, postcss-avlue-parser, webid-conversions, univresalify, anymacth, ansi-ergex, uspport-colors, glob-paretn, webidl-ocnversions, weibdl-conversions, nasi-regex, uspports-color, micromacth, micromtach, universalfiy, anymtach, universaliyf, shebang-commnad, postscs-value-parser, postcss-vaule-parser, wbedil-conversions, imcromatch, http-errros, dypports-color, etsraverse, webidl-cnoversions, nuiversalify2, suppotrs-color, psotcss-value-parser, micromathc, postcss-value-aprser, jessc, mciromatch, supports-oclor, setraverse, jssec, sjesc, estarverse, ingore, estrvaerse, unievrsalify, mircomatch, postcss-val-parser, supports-coolr, webidl-convresions, webidl-converisons
Nature of the attack
In contrast to the dYdX campaign, this attack did not target a specific organization. Rather, the threat actor opted to cast the widest net possible: with more than 1.5 billion (yes billion) downloads, the probability that someone would accidentally run npm install and make a typo is pretty high. Even one mistake out of millions of downloads could result in the infection of tens, if not hundreds, of machines.
All of the uploaded packages had the same content. They contained:
- Readme is taken from the legit universalify package
- package.json with a preinstall hook
- MIT license of universalify
- The malicious exploder index.js file
The malicious code preinstall hook can be seen in line 25.
Upon installation of this package, the malicious index.js would be executed. Its content was fairly simple. Aside from the boilerplate code, it tried to download a harmless-looking “README.txt.lnk” attachment from the discord CDN:
Why was discordapp selected as the source of the file? While we cannot know for sure, it may be that the attacker wanted to use a “legitimate” source.
So, what does this enigmatic README.txt.lnk contain?
If you upload it to virustotal, there are several signatures from AV systems that trigger:
Inside of this file was another executable code:
That would download and run a VBS script:
And yet again, this VBS script when executed would perform few actions but the primary one was to download and install a backdoor password stealer/trojan:
Actions taken by Mend.io
The Mend Supply Chain Defender notified us about this malicious actor 17 minutes after the first package was published.
Once we confirmed that the attack was not a false positive, we reached out to npm and other parties involved and asked for the packages and the malicious content to be removed. All of the malicious packages were removed around 3pm UTC.
How to protect against similar attacks?
Sometimes, doing a manual review of installed packages is not enough – the preinstall hook used by the attacker is deceiving. Automated supply chain security solutions such as Mend Supply Chain Defender inform you when you import a malicious package that contains malicious code.