Typosquatted npm packages used to steal cloud and CI/CD secrets

Threat Overview

Microsoft Security recently detailed a campaign involving typosquatted npm packages designed to steal cloud and CI/CD secrets, a critical supply chain compromise (T1195.002). This activity leverages npm lifecycle hooks (T1059.007) to execute malicious code, ultimately targeting cloud credentials (T1552.009) and establishing command and control (T1071.001) via custom HTTP headers. Our analysis focused on generating high-fidelity detections for these specific tactics.

We developed several KQL queries leveraging DeviceProcessEvents and DeviceNetworkEvents to identify this activity. One query targets the initial execution, looking for `node.exe`, `npm.exe`, or `npx.exe` processes executing `preinstall`, `postinstall`, or `install` hooks in conjunction with known malicious package names like "@vpmdhaj" or "opensearch-setup". This allows defenders to identify attempts to install these specific malicious packages within their environments.

Another query focuses on command and control, searching DeviceNetworkEvents for connections to the C2 domain "aab.sportsontheweb.net" or the presence of the unique "X-Supply: 1" HTTP header, which indicates active beaconing by the threat actor. For defense evasion (T1218), we monitor DeviceNetworkEvents for `node.exe` processes connecting to "github.com/oven-sh/bun/releases", signaling the download of the Bun runtime for proxy execution. This helps identify the setup phase of the attack.

To detect credential access attempts, a KQL query on DeviceNetworkEvents identifies `node.exe`, `bun.exe`, or `payload.bin` processes attempting to connect to cloud metadata service IPs such as "169.254.169.254" or "169.254.170.2". This directly flags attempts to steal cloud credentials (T1552.009). Finally, we also look for the persistence mechanism by identifying processes or initiating processes with "__DAEMONIZED=1" in their command line, a specific indicator of the daemonized payload.

Defenders should implement these queries to monitor for suspicious npm and node execution, network connections to known C2 infrastructure, and attempts to access cloud metadata services from development or CI/CD environments. Regular review of process command lines and network traffic from build agents is crucial for detecting such supply chain attacks.

Source

Detection Rules

Execution / T1059.007

This detection identifies the initial execution vector of the attack, where npm lifecycle hooks ('preinstall', 'install', 'postinstall') are used to run malicious code. The query is scoped to the specific malicious package names identified in the vpmdhaj campaign, making it a high-fidelity indicator of compromise. This is an ATTACKER action.

KQL
let maliciousPackages = dynamic(["@vpmdhaj", "opensearch-setup", "opensearch-setup-tool", "opensearch-config-utility", "opensearch-security-scanner", "search-engine-setup", "search-cluster-setup", "elastic-opensearch-helper", "vpmdhaj-opensearch-setup", "env-config-manager", "app-config-utility"]);
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("node.exe", "node", "npm.cmd", "npm.exe", "npx.cmd", "npx.exe")
| where ProcessCommandLine has_any ("preinstall", "postinstall", "install")
| where ProcessCommandLine has_any (maliciousPackages)
| project Timestamp, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, AccountName, AccountDomain
Command and Control / T1071.001

This query detects the unique C2 beacon of the Gen-1 stager. The combination of the specific C2 domain 'aab.sportsontheweb.net' and the custom HTTP header 'X-Supply: 1' are strong, high-fidelity indicators of this specific threat actor's malware. This is an ATTACKER action.

KQL
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where RemoteUrl has "aab.sportsontheweb.net" or AdditionalFields has "X-Supply: 1"
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteUrl, RemoteIP, AdditionalFields
| extend Actor = "vpmdhaj"
Defense Evasion / T1218

This detection targets the Gen-2 stager's technique of downloading the legitimate Bun runtime to use as a loader for its malicious payload. A Node.js or npm process initiating a download from the official Bun GitHub releases page is highly anomalous and a key behavior of this attack. This is an ATTACKER action.

KQL
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("node.exe", "node")
| where RemoteUrl has "github.com/oven-sh/bun/releases"
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteUrl
Credential Access / T1552.009

The final payload attempts to steal AWS credentials by querying the EC2 Instance Metadata Service (IMDS). A Node.js or Bun process making network connections to the IMDS endpoint (169.254.169.254) is a strong signal of credential theft activity, especially in a developer or CI/CD environment where such behavior is not standard for these processes. This is an ATTACKER action.

KQL
DeviceNetworkEvents
| where Timestamp > ago(7d)
| where RemoteIP in ("169.254.169.254", "169.254.170.2")
| where InitiatingProcessFileName in~ ("node.exe", "node", "bun", "bun.exe") or InitiatingProcessFolderPath endswith "payload.bin"
| summarize count() by Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP
Execution / T1059.007

This detection hunts for the unique environment variable '__DAEMONIZED=1' used by the malware to spawn its second stage as a detached process. This string is a custom artifact of the malware and is extremely unlikely to appear in legitimate software, making this a high-fidelity indicator of this specific campaign's execution phase. This is an ATTACKER action.

KQL
DeviceProcessEvents
| where Timestamp > ago(7d)
| where ProcessCommandLine has "__DAEMONIZED=1" or InitiatingProcessCommandLine has "__DAEMONIZED=1"
| project Timestamp, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, AccountName
Verified against live Sentinel — May 29, 2026

What This Catches

This detection logic targets specific behavioral indicators mapped to the MITRE framework as identified in the source intelligence.

MITRE ATT&CK

Tactics
ExecutionCommand and ControlDefense EvasionCredential Access
Techniques
T1059.007T1071.001T1218T1552.009

Want This Detection in Your Environment?

Overwatch deploys and manages detection rules like this across your Microsoft Sentinel workspace, with continuous tuning and 24/7 monitoring.

Book a Consultation