NEW

The Complete AI SOC Platform is here. Read the announcement →

close

The Complete AI SOC Platform is here. Read the announcement →

close

BLOG

False Claims: An npm Supply Chain Campaign Impersonates Asurion

Alessandra

Rizzo

Introduction

The Panther Threat Research Team has been tracking a sustained npm supply chain attack campaign impersonating the device insurance provider Asurion and its subsidiaries. The campaign, active from April 1 through April 8, 2026, published at least 15 malicious package versions across four scoped npm namespaces using dependency confusion and typosquatting to distribute a multi-stage credential harvester. All packages masquerade as internal React UI component libraries or e2e testing utilities. The malware extracts AWS/GCP/Azure credentials, SSH private keys, Kubernetes service account tokens, npm auth tokens, CI/CD pipeline secrets, Docker registry credentials, cloud IMDS metadata, and sensitive system files including /etc/shadow. The payload includes one of the most comprehensive sandbox evasion suites we have observed in npm malware, fingerprinting at least eight named analysis platforms. At its peak, the @sbxapps package recorded 814 weekly downloads. The C2 infrastructure evolved from a Slack webhook to an XOR-obfuscated AWS API Gateway endpoint over the course of a single week.

Campaign Overview

The attack was identified through our automated npm scanning pipeline and every package version received a unanimous malicious verdict with confidence scores between 0.98 and 1.0. Two throwaway npm accounts, both 0-day-old at time of first publication, were used to target four organizational scopes:

npm Scope

Impersonated Entity

Versions

Maintainer

@sbxapps

Asurion field service tools

v45.0.0 – v50.0.1 (8+ versions)

mclovin.hi2008

@asurion-hub-web

Asurion hub web platform

v96.0.1, v98.0.1

mclovin.hi2008

@soluto-home-web

Soluto (Asurion subsidiary)

v200.0.1, v205.0.1

mclovin.hi2008

@asurion-core

Asurion core libraries

eventualize-react- and -b v99.0.1

frankp89

Technical Analysis

Execution chain

The package.json defines preinstall/postinstall hooks that run a decoy script performing legitimate-looking dist file checks before silently calling the actual payload, preflight-check.js, inside a bare try/catch.

Starting with v46.0.0, the campaign introduced a second execution path. The package's dist/index.js entry point includes a require('./utils/analytics') call disguised as usage telemetry, which asynchronously loads the malware payload via setImmediate(). This means the malware fires at runtime when application code imports the package, regardless of whether --ignore-scripts was used during installation.

Payload stages

The payload implements a six-stage collection pipeline preceded by comprehensive anti-analysis. Annotated backup files (.bak) accidentally included in later versions confirmed the staged architecture with.

Stage 0 — Sandbox evasion. Detects 11+ analysis environments by specific fingerprints (debugger attachment, environment variable keywords, INetSim DNS entries, SupplySec/Diffend/Firecracker/Sunaba/Tencent artifacts, and others). If detected, calls process.abort(). For borderline cases, adds 60–180 second delays with jitter to outlast sandbox timeouts.

Stages 1–6 — Data collection.

  • Stage 1 — Systematically collects host info and CI/CD environment classification.

  • Stage 2 — Environment variables matching 27+ cloud/secret patterns, plus .env files, .npmrc tokens, and shell configs.

  • Stage 3 — AWS/GCP/Azure credential files, SSH private keys, Docker config, and git credentials.

  • Stage 4/etc/passwd, /etc/shadow, and container socket enumeration.

  • Stage 5 — Kubernetes service account tokens and active K8s API queries for secrets and configmaps.

  • Stage 6 — Live IMDS credential theft from AWS, GCP, Azure, and ECS metadata endpoints.

Exfiltration

All sensitive strings are stored as numeric byte arrays and decoded at runtime; the C2 URL is additionally XOR-encoded with key 90. Collected data is transmitted via HTTPS POST in 2,800-byte chunks with DJB2 hash deduplication, randomized jitter, and retry logic. A lock file prevents duplicate execution across multiple installs. Early versions (April 1–2) exfiltrated to a Slack webhook; by April 6 the actor migrated to an AWS API Gateway endpoint, and by April 7 had wrapped the URL in XOR encoding.

Who is Affected

The primary targets are presumably developers and CI/CD systems within Asurion and its subsidiaries. Any organization whose internal dependency resolution could fall back to the public npm registry, a classic dependency confusion scenario, was at risk of pulling one of these packages during a routine npm install.

Beyond the direct target, independent developers as well as any environment that happened to install one of these typosquatted packages, could also be affected. Given that the malware harvests a wide range of credentials (AWS, GCP, Azure, Kubernetes, SSH, Docker, npm tokens, and CI/CD secrets), the blast radius extends well beyond the initially compromised host to any infrastructure reachable by the stolen credentials. \

Organizations that installed any version of the @sbxapps, @asurion-hub-web, @soluto-home-web, or @asurion-core scoped packages from the public npm registry between April 1 and April 8, 2026 should consider those systems fully compromised.

Conclusion

This campaign represents a well-resourced supply chain attack with a narrow organizational target and broad credential collection scope. The actor iterated rapidly, evolving evasion and infrastructure within hours of likely detection events. The introduction of a runtime execution path through analytics.js is particularly notable: it renders --ignore-scripts, the most common developer mitigation against npm supply chain attacks, ineffective. Any system that installed these packages should be treated as fully compromised. All credentials accessible from those environments should be rotated immediately.

See it in action

Most AI closes the alert. Panther closes the loop.

Detection

rule npm_credential_harvest_preflight_check {
    meta:
        description = "Detects the preflight-check.js credential harvester payload from the Asurion-targeting npm supply chain campaign (April 2026)"
        author = "PantherLabs"
        date = "2026-04-09"

    strings:
        // XOR-encoded C2 byte array (unique to this campaign)
        $xor_array = "50,46,46,42,41,96,117,117,42,56,35,51,109,108,41,106"

        // XOR decoding function pattern
        $xor_decode = /function\\s+_dx\\s*\\(\\s*\\w+\\s*,\\s*\\w+\\s*\\)/

        // C2 endpoint builder
        $ep_func = /function\\s+_ep\\s*\\(/

        // Sandbox evasion: named platform fingerprints
        $evasion_malysis = "MALYSIS_ANALYSIS_ID"
        $evasion_rare_signer = "rare-signer"
        $evasion_sunaba = "sunaba"
        $evasion_hscan = "hscan-supplychain"
        $evasion_diffend = "diffend"
        $evasion_aspect = "aspect"

        // Stage function signatures
        $stage_s0 = /function\\s+_s0\\s*\\(/
        $stage_s1 = /function\\s+_s1\\s*\\(/
        $stage_s2 = /function\\s+_s2\\s*\\(/
        $stage_s6 = /function\\s+_s6cloud\\s*\\(/
        $stage_s5 = /function\\s+_s5k8s\\s*\\(/

        // Exfiltration function patterns
        $exfil_sendchunked = "_sendChunked"
        $exfil_queue = /function\\s+_nx\\s*\\(/
        $exfil_post = /function\\s+_ps\\s*\\(/

        // Lock file pattern
        $lockfile = ".ds-compat-"

        // Deceptive opt-out env vars
        $optout_1 = "PKG_TELEMETRY_OPTOUT"
        $optout_2 = "DS_NO_TELEMETRY"

        // Version marker pattern
        $version_marker = /var\\s+_V\\s*=\\s*['"][45]\\d\\.\\d+\\.\\d+['"]/

        // Hard abort on sandbox detection
        $hard_abort = "process.abort()"

    condition:
        $xor_array
        or ($ep_func and $hard_abort and 2 of ($evasion_*))
        or (3 of ($stage_*) and $exfil_sendchunked)
        or ($lockfile and $optout_1 and $optout_2 and $hard_abort)
        or ($version_marker and 2 of ($stage_*) and 1 of ($exfil_*))
}
rule npm_credential_harvest_preflight_check {
    meta:
        description = "Detects the preflight-check.js credential harvester payload from the Asurion-targeting npm supply chain campaign (April 2026)"
        author = "PantherLabs"
        date = "2026-04-09"

    strings:
        // XOR-encoded C2 byte array (unique to this campaign)
        $xor_array = "50,46,46,42,41,96,117,117,42,56,35,51,109,108,41,106"

        // XOR decoding function pattern
        $xor_decode = /function\\s+_dx\\s*\\(\\s*\\w+\\s*,\\s*\\w+\\s*\\)/

        // C2 endpoint builder
        $ep_func = /function\\s+_ep\\s*\\(/

        // Sandbox evasion: named platform fingerprints
        $evasion_malysis = "MALYSIS_ANALYSIS_ID"
        $evasion_rare_signer = "rare-signer"
        $evasion_sunaba = "sunaba"
        $evasion_hscan = "hscan-supplychain"
        $evasion_diffend = "diffend"
        $evasion_aspect = "aspect"

        // Stage function signatures
        $stage_s0 = /function\\s+_s0\\s*\\(/
        $stage_s1 = /function\\s+_s1\\s*\\(/
        $stage_s2 = /function\\s+_s2\\s*\\(/
        $stage_s6 = /function\\s+_s6cloud\\s*\\(/
        $stage_s5 = /function\\s+_s5k8s\\s*\\(/

        // Exfiltration function patterns
        $exfil_sendchunked = "_sendChunked"
        $exfil_queue = /function\\s+_nx\\s*\\(/
        $exfil_post = /function\\s+_ps\\s*\\(/

        // Lock file pattern
        $lockfile = ".ds-compat-"

        // Deceptive opt-out env vars
        $optout_1 = "PKG_TELEMETRY_OPTOUT"
        $optout_2 = "DS_NO_TELEMETRY"

        // Version marker pattern
        $version_marker = /var\\s+_V\\s*=\\s*['"][45]\\d\\.\\d+\\.\\d+['"]/

        // Hard abort on sandbox detection
        $hard_abort = "process.abort()"

    condition:
        $xor_array
        or ($ep_func and $hard_abort and 2 of ($evasion_*))
        or (3 of ($stage_*) and $exfil_sendchunked)
        or ($lockfile and $optout_1 and $optout_2 and $hard_abort)
        or ($version_marker and 2 of ($stage_*) and 1 of ($exfil_*))
}
rule npm_credential_harvest_preflight_check {
    meta:
        description = "Detects the preflight-check.js credential harvester payload from the Asurion-targeting npm supply chain campaign (April 2026)"
        author = "PantherLabs"
        date = "2026-04-09"

    strings:
        // XOR-encoded C2 byte array (unique to this campaign)
        $xor_array = "50,46,46,42,41,96,117,117,42,56,35,51,109,108,41,106"

        // XOR decoding function pattern
        $xor_decode = /function\\s+_dx\\s*\\(\\s*\\w+\\s*,\\s*\\w+\\s*\\)/

        // C2 endpoint builder
        $ep_func = /function\\s+_ep\\s*\\(/

        // Sandbox evasion: named platform fingerprints
        $evasion_malysis = "MALYSIS_ANALYSIS_ID"
        $evasion_rare_signer = "rare-signer"
        $evasion_sunaba = "sunaba"
        $evasion_hscan = "hscan-supplychain"
        $evasion_diffend = "diffend"
        $evasion_aspect = "aspect"

        // Stage function signatures
        $stage_s0 = /function\\s+_s0\\s*\\(/
        $stage_s1 = /function\\s+_s1\\s*\\(/
        $stage_s2 = /function\\s+_s2\\s*\\(/
        $stage_s6 = /function\\s+_s6cloud\\s*\\(/
        $stage_s5 = /function\\s+_s5k8s\\s*\\(/

        // Exfiltration function patterns
        $exfil_sendchunked = "_sendChunked"
        $exfil_queue = /function\\s+_nx\\s*\\(/
        $exfil_post = /function\\s+_ps\\s*\\(/

        // Lock file pattern
        $lockfile = ".ds-compat-"

        // Deceptive opt-out env vars
        $optout_1 = "PKG_TELEMETRY_OPTOUT"
        $optout_2 = "DS_NO_TELEMETRY"

        // Version marker pattern
        $version_marker = /var\\s+_V\\s*=\\s*['"][45]\\d\\.\\d+\\.\\d+['"]/

        // Hard abort on sandbox detection
        $hard_abort = "process.abort()"

    condition:
        $xor_array
        or ($ep_func and $hard_abort and 2 of ($evasion_*))
        or (3 of ($stage_*) and $exfil_sendchunked)
        or ($lockfile and $optout_1 and $optout_2 and $hard_abort)
        or ($version_marker and 2 of ($stage_*) and 1 of ($exfil_*))
}
rule npm_credential_harvest_preflight_check {
    meta:
        description = "Detects the preflight-check.js credential harvester payload from the Asurion-targeting npm supply chain campaign (April 2026)"
        author = "PantherLabs"
        date = "2026-04-09"

    strings:
        // XOR-encoded C2 byte array (unique to this campaign)
        $xor_array = "50,46,46,42,41,96,117,117,42,56,35,51,109,108,41,106"

        // XOR decoding function pattern
        $xor_decode = /function\\s+_dx\\s*\\(\\s*\\w+\\s*,\\s*\\w+\\s*\\)/

        // C2 endpoint builder
        $ep_func = /function\\s+_ep\\s*\\(/

        // Sandbox evasion: named platform fingerprints
        $evasion_malysis = "MALYSIS_ANALYSIS_ID"
        $evasion_rare_signer = "rare-signer"
        $evasion_sunaba = "sunaba"
        $evasion_hscan = "hscan-supplychain"
        $evasion_diffend = "diffend"
        $evasion_aspect = "aspect"

        // Stage function signatures
        $stage_s0 = /function\\s+_s0\\s*\\(/
        $stage_s1 = /function\\s+_s1\\s*\\(/
        $stage_s2 = /function\\s+_s2\\s*\\(/
        $stage_s6 = /function\\s+_s6cloud\\s*\\(/
        $stage_s5 = /function\\s+_s5k8s\\s*\\(/

        // Exfiltration function patterns
        $exfil_sendchunked = "_sendChunked"
        $exfil_queue = /function\\s+_nx\\s*\\(/
        $exfil_post = /function\\s+_ps\\s*\\(/

        // Lock file pattern
        $lockfile = ".ds-compat-"

        // Deceptive opt-out env vars
        $optout_1 = "PKG_TELEMETRY_OPTOUT"
        $optout_2 = "DS_NO_TELEMETRY"

        // Version marker pattern
        $version_marker = /var\\s+_V\\s*=\\s*['"][45]\\d\\.\\d+\\.\\d+['"]/

        // Hard abort on sandbox detection
        $hard_abort = "process.abort()"

    condition:
        $xor_array
        or ($ep_func and $hard_abort and 2 of ($evasion_*))
        or (3 of ($stage_*) and $exfil_sendchunked)
        or ($lockfile and $optout_1 and $optout_2 and $hard_abort)
        or ($version_marker and 2 of ($stage_*) and 1 of ($exfil_*))
}

IoCs

Host-Based Indicators

Type

Value

Description

Payload

scripts/preflight-check.js

Primary malware

Decoy

scripts/postflight-verify.js

Chains to payload

Bypass

dist/utils/analytics.js

Runtime --ignore-scripts bypass

Lock file

/tmp/.ds-compat-<hash>

Prevents duplicate execution

XOR key

90

C2 URL decoding key

Internal version

_V = '51.0.0' / '51.0.1' / '51.0.2'

Payload version tracker

Opt-out env

PKG_TELEMETRY_OPTOUT=1, DS_NO_TELEMETRY=1

Deceptive kill switches

Network Indicators

Type

Value

Description

Domain (C2)

pbyi76s0e9.execute-api.us-east-1[.]amazonaws[.]com

AWS API Gateway relay (Phase 2–3)

Domain (C2)

https://hooks[.]slack[.]com/services/T011WKPUSQK/B0AQ40VDQQ2/AMcxrvrLKUEXE3BCHhIa6Fu9

Slack webhook (Phase 1)

Slack IDs

T011WKPUSQK / B0AQ40VDQQ2

Attacker Slack workspace and channel

IP

169.254.169.254

Cloud IMDS (queried by malware)

Hostname

metadata.google.internal

GCP metadata (queried by malware)

Share:

Bolt-on AI closes alerts. Panther closes the loop.

See how Panther compounds intelligence across the SOC.

Bolt-on AI closes alerts. Panther closes the loop.

See how Panther compounds intelligence across the SOC.

Bolt-on AI closes alerts. Panther closes the loop.

See how Panther compounds intelligence across the SOC.

Bolt-on AI closes alerts. Panther closes the loop.

See how Panther compounds intelligence across the SOC.

Get product updates, webinars, and news

By submitting this form, you acknowledge and agree that Panther will process your personal information in accordance with the Privacy Policy.

Get product updates, webinars, and news

By submitting this form, you acknowledge and agree that Panther will process your personal information in accordance with the Privacy Policy.

Get product updates, webinars, and news

By submitting this form, you acknowledge and agree that Panther will process your personal information in accordance with the Privacy Policy.