Affected platforms: All platforms where NPM packages can be installed
Impacted parties: Any individuals or institutions that have these malicious packages installed
Impact: Leak of credentials, sensitive information, source code, etc.
Severity level: High
Over the past few months, the FortiGuard Labs team has discovered several malicious packages hidden in NPM (Node Package Manager), the largest software registry for the JavaScript programming language. These packages were found through a system dedicated to discover malicious open-source packages from various ecosystems e.g. PyPI, NPM. In this blog, we will look at some of these packages, grouping them based on similar styles of code or functions.
In general, most of these malicious packages use install scripts that run pre or post-install. Whenever an NPM package is installed, those scripts are run as well. An example of this is shown below.
Every package we found aims to steal sensitive data, such as system or user information, via a webhook or file-sharing link. Let’s explore the sets of packages below.
The First Set:
- @expue/webpack (version 0.0.3-alpha.0)
- @expue/core (version 0.0.3-alpha.0)
- @expue/vue3-renderer (version 0.0.3-alpha.0)
- @fixedwidthtable/fixedwidthtable (version 0.0.2)
- @virtualsearchtable/virtualsearchtable (version 0.1.1)
This first set shows an obfuscated index.js script. However, we can identify some clues in the strings that may raise suspicions. Let’s try to simplify this code.
After cleaning up the script, we can see it exfiltrates sensitive data, including Kubernetes configurations, SSH keys, and other critical information. It also gathers basic system fingerprinting details, like username, IP address, and hostname, without any prior warning.
The Second Set:
- binarium-crm (versions 1.0.0, 1.0.9, 1.9.9)
- career-service-client-0.1.6 (versions 0.1.6, 0.1.13, 0.1.15)
- hh-dep-monitoring (versions 0.1.5, 0.1.14)
- orbitplate (versions 1.0.4, 1.0.6)
The index.js in this second set of packages sends an HTTP GET request to a specific URL, including query parameters. It scans for particular files and directories that may contain sensitive information. This script also enables the unauthorized extraction of critical developer data, including source code and configuration files. The targeted files and directories may contain highly valuable intellectual property and sensitive information, such as various application and service credentials. It then archives these files and directories and uploads the resulting archives to an FTP server.
The Third Set:
- @zola-helpers/client (versions 1.0.1, 1.0.2, 1.0.3)
- suncorp-styleguide-base (versions 1.0.3, 1.0.4, 1.0.5)
In this set, the index.mjs install script uses a Discord webhook to exfiltrate sensitive data, such as system information, username, and folder contents.
The Fourth Set:
- @next-translate-root/i18n (versions 1.0.1, 1.0.2)
- @ag-grid-react/lib (version 1.0.1)
- @next-translate-root/locales (versions 1.0.0, 1.0.1, 1.0.2)
As with the third set, this fourth set also uses an index.mjs install script and a Discord webhook to exfiltrate sensitive data. But this time, they use an alternate style of coding.
The Fifth Set:
- @dtx-company/flowcode-generator-types (version 200000.0.2)
This fifth set uses an index.js install script to exfiltrate host and username info and home users’ home directory contents via a webhook.
The Sixth Set:
- squarespace-abtest (version 1.0.1)
- ruamel.taml.clib (version 0.1.2)
- regily (version 1.0.0)
- developer-scaffold-full-width-wrapper (versions 1.9.9, 21.0.9)
- @abb-americas/angular-utilities (version 1.0.0)
- @abb-americas/image-scaler (version 1.0.0)
- @abdulmz/mz-test (version 1.1.1)
- @ikea-aoa/component-financial-services (version 99.0.1)
- @ikea-aoa/component-lightbox (version 99.0.1)
- @ikea-aoa/component-popover (version 99.0.0)
This set—the most commonly found style—uses yet another index.js install script to exfiltrate information.
The Seventh Set:
- @cima/prism-utils (versions 23.2.1, 23.2.2)
In this set, the packages use an installer.js install script to carry out the attack, similar to the previous two, but we can see that the environment variable ‘NODE_TLS_REJECT_UNAUTHORIZED’ is set to ‘0’. This disables TLS certificate validation, which may make the connection insecure and vulnerable to man-in-the-middle attacks.
The Eighth Set:
- discorddd.jss (versions 1.4.9, 1.5.0, 1.6.4)
- saaaaaaaaaaaaaaaaaaaaaaa (version 1.4.1)
This package automatically downloads and executes a potentially malicious executable file from a URL to a C:/ directory.
The Ninth Set:
- evernote-thrift (version 1.9.99)
- en-features-rollout (version 1.90.9)
- en-conduit-electron (version 1.90.9)
- en-conduit-electron-auth (version 1.90.9)
- en-conduit-electron-worker (version1.90.9)
- en-thrift-internal (version 2.30.9)
- en-conduit-electron-renderer (version 1.90.9)
This package uses another script style to gather system information, including the victim’s public IP address and then exfiltrates this information to a discord webhook.
Conclusion
This blog groups together a collection of malicious NPM packages that use install scripts to steal users’ sensitive info based on styles of code or functions. End users should watch for packages that employ suspicious install scripts and exercise caution. We will continue hunting for and reporting malicious packages to help users avoid becoming victims.
Fortinet Protections
Fortiguard AntiVirus detects the malicious files identified in this report as
@zola-helpers/client-1.0.1 index.mjs: JS/WebHook.CNYS!tr
@zola-helpers/client-1.0.2 index.mjs: JS/WebHook.CNYS!tr
@zola-helpers/client-1.0.3 index.mjs: JS/WebHook.CNYS!tr
@next-translate-root/i18n-1.0.1 index.mjs: JS/WebHook.CNYS!tr
@next-translate-root/i18n-1.0.2 index.mjs: JS/WebHook.CNYS!tr
suncorp-styleguide-base-1.0.3 index.mjs: JS/WebHook.CNYS!tr
suncorp-styleguide-base-1.0.4 index.mjs: JS/WebHook.CNYS!tr
suncorp-styleguide-base-1.0.5 index.mjs: JS/WebHook.CNYS!tr
@ag-grid-react/lib-1.0.1 index.mjs: JS/WebHook.CNYS!tr
@next-translate-root/locales-1.0.0 index.mjs: JS/WebHook.CNYS!tr
@next-translate-root/locales-1.0.1 index.mjs: JS/WebHook.CNYS!tr
@next-translate-root/locales-1.0.2 index.mjs: JS/WebHook.CNYS!tr
@dtx-company/flowcode-generator-types-200000.0.2 index.js: JS/Agent.OAST!tr
squarespace-abtest-1.0.1 index.js: JS/Agent.OAST!tr
ruamel.taml.clib-0.1.2 index.js: JS/Agent.OAST!tr
regily-1.0.0 index.js: JS/Agent.OAST!tr
developer-scaffold-full-width-wrapper-1.9.9 index.js: JS/Agent.OAST!tr
developer-scaffold-full-width-wrapper-21.0.9 index.js: JS/Agent.OAST!tr
@abb-americas/angular-utilities-1.0.0 index.js: JS/Agent.OAST!tr
@abb-americas/image-scaler-1.0.0 index.js: JS/Agent.OAST!tr
@abdulmz/mz-test-1.1.1 index.js: JS/Agent.OAST!tr
@ikea-aoa/component-financial-services index.js: JS/Agent.OAST!tr
@ikea-aoa/component-lightbox-99.0.1 index.js: JS/Agent.OAST!tr
@ikea-aoa/component-popover-99.0.0 index.js: JS/Agent.OAST!tr
@cima/prism-utils-23.2.1 installer.js: JS/Agent.OAST!tr.dldr
@cima/prism-utils-23.2.2 installer.js: JS/Agent.OAST!tr.dldr
discorddd.jss-1.4.9 index.js: JS/Agent.CDPC!tr.dldr
discorddd.jss-1.5.0 index.js: JS/Agent.CDPC!tr.dldr
discorddd.jss-1.6.4 index.js: JS/Agent.CDPC!tr.dldr
saaaaaaaaaaaaaaaaaaaaaaa-1.4.2 index.js: JS/Agent.CDPC!tr.dldr
evernote-thrift-1.9.99 index.js: JS/WebHook.ESY!tr
en-features-rollout-1.90.9 index.js: JS/WebHook.ESY!tr
en-conduit-electron-1.90.9 index.js: JS/WebHook.ESY!tr
en-conduit-electron-auth-1.90.9 index.js: JS/WebHook.ESY!tr
en-conduit-electron-worker-1.90.9 index.js: JS/WebHook.ESY!tr
en-thrift-internal-2.30.9 index.js: JS/WebHook.ESY!tr
en-conduit-electron-renderer-1.90.9 index.js: JS/WebHook.ESY!tr
@expue/webpack-0.0.3-alpha.0 index.js: JS/Agent.ATTC!tr
@expue/core-0.0.3-alpha.0 index.js: JS/Agent.ATTC!tr
@expue/vue3-renderer-0.0.3-alpha.0 index.js: JS/Agent.ATTC!tr
@fixedwidthtable/fixedwidthtable-0.0.2 index.js: JS/Agent.ATTC!tr
@virtualsearchtable/virtualsearchtable-0.1.1 index.js: JS/Agent.ATTC!tr
binarium-crm 1.0.0 index.js: JS/Agent.CFRE!tr.dldr
binarium-crm 1.0.9 index.js: JS/Agent.CFRE!tr.dldr
binarium-crm 1.9.9 index.js: JS/Agent.CFRE!tr.dldr
career-service-client-0.1.6 index.js: JS/Agent.CFRE!tr.dldr
career-service-client-0.1.13 index.js: JS/Agent.CFRE!tr.dldr
career-service-client-0.1.15 index.js: JS/Agent.CFRE!tr.dldr
hh-dep-monitoring-0.1.5 index.js: JS/Agent.CFRE!tr.dldr
hh-dep-monitoring-0.1.14 index.js: JS/Agent.CFRE!tr.dldr
orbitplate-1.0.4 index.js: JS/Agent.CFRE!tr.dldr
orbitplate-1.0.6 index.js: JS/Agent.CFRE!tr.dldr
The FortiGuard AntiVirus service is supported by FortiGate, FortiMail, FortiClient, and FortiEDR. Customers running current AntiVirus updates are protected.
The FortiGuard Web Filtering Service detects and blocks the download URLs cited in this report as Malicious.
TheFortiDevSec SCA scanner detects malicious packages, including those cited in this report that may operate as dependencies in users’ projects in test phases, and prevents those dependencies from being introduced into users’ products.
If you believe these or any other cybersecurity threat has impacted your organization, please contact our Global FortiGuard Incident Response Team.
IOCs
@zola-helpers/client-1.0.1 index.mjs
MD5: e905c2915762e6c1fa57ff3b444411da
@zola-helpers/client-1.0.2 index.mjs
MD5: 1e5a38b17453379af9107a9afce0963f
@zola-helpers/client-1.0.3 index.mjs
MD5: c7325f2347833eba9869926226027330
@next-translate-root/i18n-1.0.1 index.mjs
MD5: cb37bd25c3011ffdd10c0db976c77b45
@next-translate-root/i18n-1.0.2 index.mjs
MD5: c4bf513d91909de6d8c8e28fe317950a
suncorp-styleguide-base-1.0.3 index.mjs
MD5: 404c75ee8c8a2241e94773a5f46cd372
suncorp-styleguide-base-1.0.4 index.mjs
MD5: 0b4da6e4a3d7f0d43afc1ce5a567aeed
suncorp-styleguide-base-1.0.5 index.mjs
MD5: fbf108d9534e2a065ba62198d7ab226c
@ag-grid-react/lib-1.0.1 index.mjs
MD5: 42d7f4f9e4d837c5f1217165e92d0136
@next-translate-root/locales-1.0.0 index.mjs
MD5: 312368807bee4e8876acec4dba528f13
@next-translate-root/locales-1.0.1 index.mjs
MD5: cb37bd25c3011ffdd10c0db976c77b45
@next-translate-root/locales-1.0.2 index.mjs
MD5: c4bf513d91909de6d8c8e28fe317950a
@dtx-company/flowcode-generator-types-200000.0.2 index.js
MD5: 1b80da13c2d440b51de3e3b1f84b30b6
squarespace-abtest-1.0.1 index.js
MD5: 0976fc4401a315d8182828d07b0e4a02
ruamel.taml.clib-0.1.2 index.js
MD5: 489af9e516d133f8341bc50068b3a505
regily-1.0.0 index.js
MD5: 8333f68439addfe5d80d7cf8646d74f6
developer-scaffold-full-width-wrapper-1.9.9 index.js
MD5: c627ce5ec695ea663b88a09fb31ea319
developer-scaffold-full-width-wrapper-21.0.9 index.js
MD5: 563cf757e5f61a592f53506c81360e4a
@abb-americas/angular-utilities-1.0.0 index.js
MD5: 2965d88976fee79d1e3ef69e5edc5d83
@abb-americas/image-scaler-1.0.0 index.js
MD5: 0876c5969dc829f2f56b455ae38a2536
@abdulmz/mz-test-1.1.1 index.js
MD5: ecd47a29a7e5132f94b1c7c0689e2e5a
@ikea-aoa/component-financial-services-99.0.1 index.js
MD5: 025809495e179b4f7ef0db8af88381e7
@ikea-aoa/component-lightbox-99.0.1 index.js
MD5: 025809495e179b4f7ef0db8af88381e7
@ikea-aoa/component-popover-99.0.0 index.js
MD5: 025809495e179b4f7ef0db8af88381e7
@cima/prism-utils-23.2.1 installer.js
MD5: 42d84beccb38c08700920b70549f5a87
@cima/prism-utils-23.2.2 installer.js
MD5: 25de187869441c3aa506ddc5fe6839ea
discorddd.jss-1.4.9 index.js
MD5: dc60d3e82ff0273309a2a9e1b7f89ea3
discorddd.jss-1.5.0 index.js
MD5: 740eca0a347fe0d0aa8ca8ec4ebf2dd2
discorddd.jss-1.6.4 index.js
MD5: 5182a61ee33247e2a426c4ddfe8196dc
saaaaaaaaaaaaaaaaaaaaaaa-1.4.2 index.js
MD5: 8458b6a4196e5d86e241c758ce89d1e5
evernote-thrift-1.9.99 index.js
MD5: 359f456996c39e7882afeda8fbbf226f
en-features-rollout-1.90.9 index.js
MD5: 0f67856db1e0c466d13079cc9cb16963
en-conduit-electron-1.90.9 index.js
MD5: 0f67856db1e0c466d13079cc9cb16963
en-conduit-electron-auth-1.90.9 index.js
MD5: 0f67856db1e0c466d13079cc9cb16963
en-conduit-electron-worker-1.90.9 index.js
MD5: 0f67856db1e0c466d13079cc9cb16963
en-thrift-internal-2.30.9 index.js
MD5: 0f67856db1e0c466d13079cc9cb16963
en-conduit-electron-renderer-1.90.9 index.js
MD5: 0f67856db1e0c466d13079cc9cb16963
@expue/webpack-0.0.3-alpha.0 index.js
MD5: 084c4c5a1d36fbdab6705a2fbd7e849e
@expue/core-0.0.3-alpha.0 index.js
MD5: 8b82f6112b22bd67cccc4ad238bfea7c
@expue/vue3-renderer-0.0.3-alpha.0 index.js
MD5: 084c4c5a1d36fbdab6705a2fbd7e849e
@fixedwidthtable/fixedwidthtable-0.0.2 index.js
MD5: 084c4c5a1d36fbdab6705a2fbd7e849e
@virtualsearchtable/virtualsearchtable-0.1.1 index.js
MD5: 37f9d6a97af8d7589bbc11aadcf185ec
binarium-crm-1.0.0 index.js
MD5: acf9777d3fabc82b49ddb096147de6a9
binarium-crm-1.0.9 index.js
MD5: acf9777d3fabc82b49ddb096147de6a9
binarium-crm-1.9.9 index.js
MD5: acf9777d3fabc82b49ddb096147de6a9
career-service-client-0.1.6 index.js
MD5: 3d1dbd501ebaae4745f6ec37850f9ff5
career-service-client-0.1.13 index.js
MD5: 3d1dbd501ebaae4745f6ec37850f9ff5
career-service-client-0.1.15 index.js
MD5: 3d1dbd501ebaae4745f6ec37850f9ff5
hh-dep-monitoring-0.1.5 index.js
MD5: 3d1dbd501ebaae4745f6ec37850f9ff5
hh-dep-monitoring-0.1.14 index.js
MD5: 3d1dbd501ebaae4745f6ec37850f9ff5
orbitplate-1.0.4 index.js
MD5: 3d1dbd501ebaae4745f6ec37850f9ff5
orbitplate-1.0.6 index.js
MD5: 3d1dbd501ebaae4745f6ec37850f9ff5
Source: https://www.fortinet.com/blog/threat-research/malicious-packages-hiddin-in-npm