TLP: WHITE | Intelligence Category: Active Malware Campaigns & Criminal Tooling | Reference Pulse: Equation of Compromise (AlienVault, modified 2026-09-22)
Threat Summary
Live OTX telemetry confirms a sophisticated, six-month supply-chain operation targeting quantitative finance and DeFi developers through the npm ecosystem. The adversary published malicious packages disguised as legitimate mathematics and linear-algebra libraries, then artificially inflated download counts to manufacture credibility in search results and dependency-selection workflows.
The attack chain is notable for its conditional trigger design: the embedded encrypted loader does not execute at install time or on import. It detonates only when a developer's code performs a specific cryptographic operation — solving a linear equation against a predetermined matrix. This means sandbox detonation, CI/CD scanning, and most dynamic analysis pipelines never see the payload fire, because the analyst must reproduce the exact mathematical invocation the operators anticipated.
Once triggered, the loader decrypts its second stage and retrieves command-and-control instructions from the Ethereum Sepolia testnet, reading attacker-controlled data stored in smart contract state. This blockchain-based dead-drop resolver gives the campaign takedown-resistant, pseudonymous C2 infrastructure — there is no domain to sinkhole and no VPS to seize. GitHub Actions abuse is used as a downstream execution and exfiltration vector, riding developer CI credentials. Objective: theft of cryptocurrency wallets, private keys, signing credentials, and access to smart-contract deployment pipelines within finance and technology organizations.
Threat Actor / Malware Profile
Attribution: Unknown. No named actor or malware family is currently associated with the campaign; tradecraft overlaps with prior North Korean-aligned and financially motivated crypto-theft operations, but no firm attribution is published.
- Distribution method: Malicious npm packages masquerading as mathematics/linear-equation libraries; typosquatting and SEO-style download inflation to boost apparent legitimacy; installation via routine
npm installby DeFi and quant developers. - Payload behavior: Encrypted loader embedded in package code; activates exclusively when the victim's own code solves a linear equation using predetermined matrices. The correct input acts as the decryption key/trigger — a rare example of environment-keyed, input-gated execution in a supply-chain context.
- C2 communication: Ethereum Sepolia testnet smart contracts used as a dead-drop resolver. The payload queries contract storage (JSON-RPC calls such as
eth_call/eth_getStorageAt) to retrieve live C2 addresses or next-stage payloads. Traffic appears as benign Web3/RPC HTTPS — indistinguishable from legitimate DeFi developer activity. - Persistence mechanism: Achieved through dependency entrenchment — the malicious package persists inside
node_modules, lockfiles, and downstream builds; GitHub Actions abuse provides recurring execution whenever CI pipelines run, effectively converting build runners into persistence hosts. - Anti-analysis techniques: Input-gated decryption (sandbox-evasive), legitimate-library camouflage, blockchain C2 (no seizable infrastructure), traffic blending with developer Web3 tooling, and staged payload delivery only after successful mathematical trigger.
IOC Analysis
The pulse carries three MD5 file hashes — characteristic of malicious npm package artifacts (tarball contents, loader scripts, or second-stage payloads):
91e020c13cb97a6365135b53b0d0fe5f(FileHash-MD5)d3d6e819028346a0b973bd5dd371c468(FileHash-MD5)dc7257d09fab42eca2c354c32fec1938(FileHash-MD5)
Operationalization guidance for SOC teams:
- Hash matching: Push the MD5s into your EDR blocklists (CrowdStrike custom IOC, Defender
BlockFileindicators, SentinelThreatIntelligenceIndicator) and retro-huntDeviceFileEvents/FileCreatedtelemetry across developer workstations and build runners. - npm artifact hunting: Hash-matching alone is insufficient — adversaries republish packages. Sweep all
node_modulesdirectories and npm caches (~/.npm/_cacache) on developer endpoints and CI runners. Compare package integrity hashes against lockfiles (package-lock.json/yarn.lock) and the public registry. - Behavioral detection: Because C2 is blockchain-resident, network IOCs are weak. Prioritize behavioral detections: Node.js processes making JSON-RPC calls to Sepolia endpoints (
*.sepolia.org,rpc.sepolia.org, Infura/Alchemy endpoints witheth_callpayloads), and unexpectednodechild processes spawned during builds. - Tooling: Use
npm audit, Socket.dev / Phylum / JFrog Xray for package reputation, and YARA scanning of npm cache contents for the encrypted loader's structure.
Detection Engineering
---
title: Node.js Process Querying Ethereum Sepolia RPC Endpoint
id: 8f3a1c2e-7b4d-4e6f-9a1b-2c5d8e9f0a11
status: experimental
description: Detects node.exe/node processes initiating network connections to Ethereum Sepolia testnet RPC endpoints, consistent with smart-contract-based C2 dead-drop resolution used by the Equation of Compromise npm supply-chain campaign.
author: Security Arsenal Threat Intelligence
references:
- https://research.jfrog.com/post/equation-of-compromise/
- https://otx.alienvault.com/pulse/
date: 2026/09/23
logsource:
category: network_connection
product: windows
definition: Requires Sysmon Event ID 3 or equivalent network connection logging
detection:
selection_process:
Image|endswith:
- '\node.exe'
- '\node'
selection_destination:
DestinationHostname|contains:
- 'sepolia.org'
- 'sepolia.infura.io'
- 'eth-sepolia'
- 'sepolia.g.alchemy.com'
condition: selection_process and selection_destination
falsepositives:
- Legitimate DeFi/Web3 developers testing contracts against Sepolia testnet
level: medium
tags:
- attack.command_and_control
- attack.t1071.001
- attack.t1102
---
title: Suspicious Child Process Spawned by Node During Build or Package Execution
id: 9b4c2d3f-8c5e-4f7a-ab2c-3d6e9f1a2b22
status: experimental
description: Detects node.exe spawning shell, script, or credential-access child processes — a common post-decryption execution pattern for npm supply-chain loaders abusing postinstall hooks and GitHub Actions runners.
author: Security Arsenal Threat Intelligence
references:
- https://research.jfrog.com/post/equation-of-compromise/
date: 2026/09/23
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\node.exe'
- '\npm.cmd'
- '\npm.exe'
selection_child:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
- '\cmd.exe'
- '\curl.exe'
- '\wget.exe'
- '\certutil.exe'
condition: selection_parent and selection_child
falsepositives:
- Legitimate npm lifecycle scripts (postinstall) in trusted build pipelines
- Developer tooling and package build steps
level: high
tags:
- attack.execution
- attack.t1059
- attack.t1195.002
---
title: Malicious npm Loader File Hash Match — Equation of Compromise Campaign
id: ac5d3e4a-9d6f-4a8b-bc3d-4e7f0a2b3c33
status: experimental
description: Detects file creation or execution events matching MD5 hashes of malicious npm package artifacts from the Equation of Compromise supply-chain campaign targeting DeFi and quantitative developers.
author: Security Arsenal Threat Intelligence
references:
- https://research.jfrog.com/post/equation-of-compromise/
date: 2026/09/23
logsource:
category: file_event
product: windows
detection:
selection_hashes:
MD5:
- '91e020c13cb97a6365135b53b0d0fe5f'
- 'd3d6e819028346a0b973bd5dd371c468'
- 'dc7257d09fab42eca2c354c32fec1938'
condition: selection_hashes
falsepositives:
- None expected; these hashes are confirmed malicious campaign artifacts
level: critical
tags:
- attack.t1195.002
- attack.initial_access
// Hunt: npm supply-chain campaign — blockchain C2, loader hashes, and node-spawned children
let BadHashes = dynamic(["91e020c13cb97a6365135b53b0d0fe5f", "d3d6e819028346a0b973bd5dd371c468", "dc7257d09fab42eca2c354c32fec1938"]);
let FileHits = DeviceFileEvents
| where TimeGenerated > ago(14d)
| where MD5 in~ (BadHashes)
| project TimeGenerated, DeviceName, FolderPath, FileName, MD5, InitiatingProcessCommandLine;
let BlockchainC2 = DeviceNetworkEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessFileName =~ "node.exe"
| where RemoteUrl has_any ("sepolia", "infura.io", "alchemy.com", "quicknode")
| project TimeGenerated, DeviceName, RemoteUrl, RemoteIP, InitiatingProcessCommandLine;
let SuspiciousChildren = DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessFileName in~ ("node.exe", "npm.cmd", "npm.exe")
| where FileName in~ ("powershell.exe", "pwsh.exe", "cmd.exe", "curl.exe", "certutil.exe")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessCommandLine;
union FileHits, BlockchainC2, SuspiciousChildren
| sort by TimeGenerated desc
# Equation of Compromise — npm supply-chain IOC hunt script
# Checks npm caches, node_modules, running Node processes, and blockchain RPC connections
$badHashes = @("91e020c13cb97a6365135b53b0d0fe5f","d3d6e819028346a0b973bd5dd371c468","dc7257d09fab42eca2c354c32fec1938")
Write-Host "=== [1/4] Hash sweep: npm cache and node_modules ===" -ForegroundColor Cyan
$searchRoots = @("$env:APPDATA\npm-cache", "$env:LOCALAPPDATA\npm-cache", "$env:USERPROFILE\.npm\_cacache", "C:\dev", "C:\projects", "C:\actions-runner")
foreach ($root in $searchRoots) {
if (Test-Path $root) {
Get-ChildItem -Path $root -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { $_.Length -lt 50MB } |
ForEach-Object {
$h = (Get-FileHash -Algorithm MD5 -Path $_.FullName -ErrorAction SilentlyContinue).Hash
if ($badHashes -contains $h.ToLower()) {
Write-Host "[HIT] $($_.FullName) MD5=$h" -ForegroundColor Red
}
}
}
}
Write-Host "=== [2/4] Running Node.js processes and command lines ===" -ForegroundColor Cyan
Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
Select-Object ProcessId, CommandLine, ExecutablePath | Format-List
Write-Host "=== [3/4] Active connections to blockchain RPC endpoints ===" -ForegroundColor Cyan
Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue |
Where-Object { $_.OwningProcess -in (Get-Process node -ErrorAction SilentlyContinue).Id } |
ForEach-Object {
$resolved = (Resolve-DnsName $_.RemoteAddress -ErrorAction SilentlyContinue).NameHost
if ($resolved -match "sepolia|infura|alchemy|quicknode") {
Write-Host "[C2 SUSPECT] PID $($_.OwningProcess) -> $($_.RemoteAddress):$($_.RemotePort) ($resolved)" -ForegroundColor Red
}
}
Write-Host "=== [4/4] GitHub Actions runner artifacts ===" -ForegroundColor Cyan
Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object { $_.TaskName -match "actions|runner" } | Format-List TaskName, State
Get-Service -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "actions.runner" } | Format-List Name, Status, StartType
Write-Host "Hunt complete. Escalate any [HIT] or [C2 SUSPECT] findings to IR immediately." -ForegroundColor Green
Response Priorities
Immediate (0–4 hours):
- Push the three MD5 hashes to EDR/AV blocklists and retro-hunt file telemetry across all developer workstations, CI runners, and build agents.
- Hunt for Node.js processes making outbound connections to Sepolia/Web3 RPC endpoints from non-Web3 engineering assets.
- Audit
package-lock.json/yarn.lockfiles in active repositories against the known-malicious package set; freeze dependency updates pending review.
24 hours:
- Because this campaign targets developer credentials, signing keys, and crypto wallets: force rotation of npm tokens, GitHub personal access tokens, CI/CD secrets, and any cryptocurrency private keys stored on or reachable from affected endpoints.
- Review GitHub Actions logs for anomalous workflow runs, unexpected outbound connections, or secrets access by unfamiliar steps; revoke runner registrations on suspect hosts.
- Verify whether any smart-contract deployment pipelines executed from compromised machines — assess on-chain exposure before key rotation closes the window.
1 week:
- Enforce a package-allowlist/proxy (Artifact Registry, Nexus, or Verdaccio with curated upstreams) for all npm installs; disable direct registry access on build runners.
- Deploy a package-reputation scanning gate (Socket, Phylum, Xray) in CI before dependency merge; alert on packages with recent publish dates, download-count anomalies, or install scripts.
- Segment CI/CD runners with egress filtering that blocks arbitrary RPC/Web3 endpoints for non-Web3 workloads; require code-signing and hash pinning for all internal build artifacts.
Related Resources
Security Arsenal Incident Response Managed SOC & MDR Services AlertMonitor Threat Detection From The Dark Side Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.