Malware Analysis: Anatomy of a WordPress Attack

In January 2025, security analysts stumbled upon a WordPress plugin that, at first glance, looked like any other. The code was clean, the comments were in place, and nothing in the formatting screamed “malware.” Only the author’s name stood out as an early hint that something was amiss.

This wasn’t the first time we’ve seen malware masquerading as a legitimate plugin. Last June, a supply chain attack leveraged AI-generated code to slip malicious plugins into WordPress sites, exploiting the trust users place in open-source software. Strikingly similar, both attacks employed well-commented code, incrementally developed features, and stealthy modifications to bypass detection.

Dissecting the Malicious Plugin

The plugin’s initial payload is deceptively simple. It includes a function, check_special_link, hooked to WordPress’s init action. Anyone can trigger this “alive check” by sending a GET request with the check_plugin parameter. These requests leave a trail in access logs and this a small but critical indicator for those monitoring for early warning signs of a cyberattack.

But the real danger lies deeper. The plugin exposes a backdoor via emergency_login_all_admins. With the right clear-text password, an attacker can enumerate administrator accounts and log in as any admin, no brute force required. Again, this is triggered via a GET parameter and leaves fingerprints on server logs.

A more insidious feature is the abuse of the WordPress REST API. The plugin registers a custom REST route, allowing unauthenticated remote code execution. Attackers can POST commands to insert arbitrary PHP code into every theme’s header.php file or clear cache plugins, all without permission checks. Even basic sanitisation is present, likely a byproduct of AI-generated code, which sometimes outpaces human malware authors in attention to detail.

Persistence and Evasion Tactics

To avoid detection, the plugin hides itself from the WordPress admin dashboard. The hide_plugin_from_list function ensures that even vigilant site owners won’t see it on the plugin list. This is a classic move in WordPress malware, designed to keep the attack under the radar for as long as possible.

Persistence is handled through a compromised wp-cron.php file. This file, a core part of WordPress’s task scheduler, is modified to reinstall the malicious plugin if it’s deleted. The code checks for the plugin’s existence and, if missing, writes it back to disk and reactivates it. The infection cycle continues until every trace is eradicated.

Command & Control and Code Injection

Recent variants of this malware have upped the ante. Upon activation, the plugin schedules a recurring event that pings a command-and-control (C&C) server in Cyprus every minute. The server receives the site URL and a timestamp, giving attackers a live inventory of compromised sites.

The code injection mechanism has also evolved. Instead of hardcoding malicious scripts, the plugin fetches a base64-encoded URL from a remote server, decodes it, and injects a JavaScript payload into the site’s header files. This allows attackers to rotate payloads and maintain control, even if the original distribution site is taken down.

A separate function allows attackers to update the injected script’s URL via a GET parameter. While the current malware version doesn’t retrieve this value, it’s a sign that the codebase is still under active development.

Indicators of Compromise and Intrusion Vectors

Victims may notice odd requests to the C&C server at 45.61.136.85, the presence of the emergency_login parameter in access logs, or unexplained changes to wp-cron.php and theme header files. Folders named ‘patterns’ in theme directories and suspiciously named plugin files-like WP-antymalwary-bot.php, addons.php, or wp-performance-booster.php-are red flags.

The initial infection vector remains unclear, but evidence points to compromised hosting accounts or stolen FTP credentials. Once inside, the malware spreads laterally, modifying core files and maintaining persistence through clever use of WordPress internals.

Lessons for Defenders

This attack highlights the need for layered WordPress security. Regularly audit plugins and core files, monitor access logs for unusual GET parameters, and deploy file integrity monitoring. Most importantly, don’t assume that a clean admin dashboard means a clean site-malware authors are getting better at hiding in plain sight.

If you find yourself cleaning up after such an intrusion, don’t just delete the plugin. Check wp-cron.php, theme header files, and the entire plugins directory for remnants. Change all credentials, audit user accounts, and consider a full site restore from a known good backup.

As always, the best defence is a healthy dose of paranoia. In cybersecurity, assume compromise and verify everything. It’s that mentality that distinguishes those who succeed from those who fail spectacularly.

For more insightful and engaging write-ups, visit kosokoking.com and stay ahead in the world of cybersecurity!

Leave a Reply

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

RELATED

Login Form: The Web’s Vulnerable Attack Surface

Discover how login forms work and their security vulnerabilities. Learn to use Hydra for ethical testing and protect against brute…

Basic HTTP Authentication Security Risks & Hydra

Learn how Basic HTTP Authentication works, its vulnerabilities, and how attackers use Hydra for brute-force attacks. Secure your web applications…

Hydra: Brute-Force Testing & Defence

Master Hydra and learn brute-force attack techniques, defence strategies, and security best practices for SSH, HTTP, RDP, and more.

Dictionary Attacks: Exploiting Human Vulnerability

Explore how dictionary attacks exploit human predictability in password creation, their impact on cybersecurity, and strategies to mitigate risks effectively.