← Back to list

How to Check Your Wordpress with Essential Plugin Backdoor with bash script solution

A trusted 31 WordPress plugins, installed over 4 million times, was quietly turned into a malware delivery network from April 2026.

Andrea Tadioli · 2026-04-21 04:21 · 0 claps · 5.9 min read paywalled
#wordpress #backdoor #web-security #wordpress-plugins #malware
Open on Medium ↗
Wiki topics: 🔒 · Cybersecurity 🔧 · Data Engineering 📰 · Journalism & News

How to Check Your Wordpress with Essential Plugin Backdoor — Yes, 31 WordPress Plugins Were Compromised

A trusted WordPress plugin portfolio — installed over 4 million times — was quietly turned into a malware delivery network. Here is what happened and how to check if your sites were affected.

1. What Happened

In early April 2026, security researcher Austin Ginder (Anchor Hosting) discovered that a client site had been injected with hidden SEO spam. The culprit was a plugin called Countdown Timer Ultimate, part of a 30+ plugin portfolio originally built by an India-based team operating under the names WP Online Support and later Essential Plugin.

The portfolio had been sold in early 2025 on Flippa — a marketplace for buying and selling online businesses — for a six-figure sum. The buyer, identified only as “Kris,” had a background in SEO, crypto, and online gambling marketing. Flippa even published a case study celebrating the sale.

The very first SVN commit made by the new owner was the backdoor.

The malicious code sat dormant for 8 months before being activated on April 5–6, 2026. On April 7, WordPress.org permanently closed all 31 plugins in a single day.

2. How the Backdoor Worked

The backdoor was introduced in version 2.6.7, released on August 8, 2025. The changelog read: “Check compatibility with WordPress version 6.8.2.” What it actually did was add 191 lines of malicious code to the wpos-analytics module.

The attack chain worked like this:

  1. A new fetch_ver_info() method called file_get_contents() on the attacker's server and passed the response directly to @unserialize() — a classic PHP deserialization RCE vulnerability.
  2. An unauthenticated REST API endpoint with permission_callback: __return_true allowed anyone to trigger the function remotely.
  3. Once activated, the plugin phoned home to analytics.essentialplugin.com, downloaded a backdoor file called wp-comments-posts.php (designed to mimic the legitimate core file wp-comments-post.php), and used it to inject ~6KB of PHP into wp-config.php.

The injected code fetched spam links, redirects, and fake pages from a command-and-control server — but only served them to Googlebot, making the infection completely invisible to site owners browsing their own sites.

The most sophisticated part: the C2 domain was resolved through an Ethereum smart contract, querying public blockchain RPC endpoints. Traditional domain takedowns would not work because the attacker could update the smart contract at any time to point to a new server.

3. The Full List of Compromised Plugins

On April 7, 2026, WordPress.org permanently closed all of the following plugins. If any of these are installed on your sites, act now.

  • Accordion and Accordion Slider — accordion-and-accordion-slider
  • Album and Image Gallery Plus Lightbox — album-and-image-gallery-plus-lightbox
  • Audio Player with Playlist Ultimate — audio-player-with-playlist-ultimate
  • Blog Designer for Post and Widget — blog-designer-for-post-and-widget
  • Countdown Timer Ultimate — countdown-timer-ultimate
  • Featured Post Creative — featured-post-creative
  • Footer Mega Grid Columns — footer-mega-grid-columns
  • Hero Banner Ultimate — hero-banner-ultimate
  • HTML5 VideoGallery Plus Player — html5-videogallery-plus-player
  • Meta Slider and Carousel with Lightbox — meta-slider-and-carousel-with-lightbox
  • Popup Anything on Click — popup-anything-on-click
  • Portfolio and Projects — portfolio-and-projects
  • Post Category Image with Grid and Slider — post-category-image-with-grid-and-slider
  • Post Grid and Filter Ultimate — post-grid-and-filter-ultimate
  • Preloader for Website — preloader-for-website
  • Product Categories Designs for WooCommerce — product-categories-designs-for-woocommerce
  • Responsive WP FAQ with Category — sp-faq
  • SlidersPack — All in One Image Sliders — sliderspack-all-in-one-image-sliders
  • SP News And Widget — sp-news-and-widget
  • Styles for WP PageNavi — Addon — styles-for-wp-pagenavi-addon
  • Ticker Ultimate — ticker-ultimate
  • Timeline and History Slider — timeline-and-history-slider
  • Woo Product Slider and Carousel with Category — woo-product-slider-and-carousel-with-category
  • WP Blog and Widgets — wp-blog-and-widgets
  • WP Featured Content and Slider — wp-featured-content-and-slider
  • WP Logo Showcase Responsive Slider and Carousel — wp-logo-showcase-responsive-slider-slider
  • WP Responsive Recent Post Slider — wp-responsive-recent-post-slider
  • WP Slick Slider and Image Carousel — wp-slick-slider-and-image-carousel
  • WP Team Showcase and Slider — wp-team-showcase-and-slider
  • WP Testimonial with Widget — wp-testimonial-with-widget
  • WP Trending Post Slider and Widget — wp-trending-post-slider-and-widget

4. How to Check Your Sites

Check wp-config.php manually

The malware injects itself on the same line as:

require_once ABSPATH . 'wp-settings.php';

If your wp-config.php is significantly larger than expected — the injected payload adds approximately 6KB — your site was actively compromised and needs a full cleanup beyond just removing the plugin.

wc -c wp-config.php
# Healthy file: ~3,000–4,000 bytes
# Compromised file: ~9,000+ bytes

Scan multiple servers via SSH (bash script)

If you manage multiple WordPress sites across different servers, you can run this script remotely from your local machine without copying anything to the server:

ssh root@YOUR_SERVER_IP 'bash -s' < check-essential-plugins.sh

Save this as check-essential-plugins.sh on your local machine:

#!/bin/bash
SLUGS=(
  "accordion-and-accordion-slider"
  "album-and-image-gallery-plus-lightbox"
  "audio-player-with-playlist-ultimate"
  "blog-designer-for-post-and-widget"
  "countdown-timer-ultimate"
  "featured-post-creative"
  "footer-mega-grid-columns"
  "hero-banner-ultimate"
  "html5-videogallery-plus-player"
  "meta-slider-and-carousel-with-lightbox"
  "popup-anything-on-click"
  "portfolio-and-projects"
  "post-category-image-with-grid-and-slider"
  "post-grid-and-filter-ultimate"
  "preloader-for-website"
  "product-categories-designs-for-woocommerce"
  "sp-faq"
  "sliderspack-all-in-one-image-sliders"
  "sp-news-and-widget"
  "styles-for-wp-pagenavi-addon"
  "ticker-ultimate"
  "timeline-and-history-slider"
  "woo-product-slider-and-carousel-with-category"
  "wp-blog-and-widgets"
  "wp-featured-content-and-slider"
  "wp-logo-showcase-responsive-slider-slider"
  "wp-responsive-recent-post-slider"
  "wp-slick-slider-and-image-carousel"
  "wp-team-showcase-and-slider"
  "wp-testimonial-with-widget"
  "wp-trending-post-slider-and-widget"
)

echo "=============================="
echo " Essential Plugin Backdoor Check"
echo " $(date)"
echo "=============================="

WP_CONFIGS=$(find /var/www -name "wp-config.php" 2>/dev/null)
if [ -z "$WP_CONFIGS" ]; then
  echo "No WordPress installations found under /var/www"
  exit 0
fi
for CONFIG in $WP_CONFIGS; do
  WP_ROOT=$(dirname "$CONFIG")
  PLUGINS_DIR="$WP_ROOT/wp-content/plugins"
  echo ""
  echo "--- Site: $WP_ROOT ---"
  CONFIG_SIZE=$(wc -c < "$CONFIG")
  if [ "$CONFIG_SIZE" -gt 6000 ]; then
    echo "ALT! wp-config.php suspicious: ${CONFIG_SIZE} bytes (possible infection!)"
  else
    echo "wp-config.php OK: ${CONFIG_SIZE} bytes"
  fi
  FOUND=0
  for SLUG in "${SLUGS[@]}"; do
    if [ -d "$PLUGINS_DIR/$SLUG" ]; then
      echo "ALT! Compromised plugin found: $SLUG"
      FOUND=1
    fi
  done
  if [ "$FOUND" -eq 0 ]; then
    echo "No compromised plugins found"
  fi
done
echo ""
echo "=============================="
echo " Scan complete"
echo "=============================="

The script finds all WordPress installations under /var/www, checks the size of each wp-config.php, and reports any of the 31 compromised plugin slugs found in the plugins directory.

If you find a compromised plugin

WordPress.org issued a forced auto-update to version 2.6.9.1 which neutralized the phone-home mechanism — but it did not clean wp-config.php. If you find one of these plugins, you should:

  1. Remove the plugin entirely
  2. Check wp-config.php for injected code after require_once ABSPATH . 'wp-settings.php';
  3. If compromised, restore wp-config.php from a clean backup and run a full malware scan

5. What WordPress.org Did

Once the attack was discovered, the response was swift. On April 7, 2026, the WordPress.org Plugins Team permanently closed all 31 plugins in a single day. On April 8, an automatic forced update to version 2.6.9.1 was pushed to all sites still running these plugins, adding return; statements to disable the phone-home functions.

This was a band-aid, not a full fix. The wpos-analytics module with all its malicious code remained in place — only the activation trigger was neutralized. The analytics.essentialplugin.com endpoint now returns {"message":"closed"}.

6. The Real Problem

This is not an isolated incident. In 2017, a buyer purchased the Display Widgets plugin (200,000 installs) for $15,000 and injected spam. The Essential Plugin case is the same playbook at a much larger scale.

WordPress.org has no mechanism to flag or review plugin ownership transfers. There is no change-of-control notification to users. No additional code review triggered by a new committer. The Flippa listing for Essential Plugin was public. The buyer’s background in SEO and gambling marketing was public. Eight months passed between the backdoor being planted and being caught.

Trust is the attack vector. The plugins were installed because they had years of legitimate history. The backdoor was dormant long enough to avoid suspicion. And when it activated, it hid its output from everyone except search engine crawlers.

If you manage WordPress sites, this case is a reminder that plugin provenance matters as much as plugin functionality. Keep an eye on ownership changes, monitor for unexpected growth in core file sizes, and check your fleet regularly.

Sources: Austin Ginder — Anchor Hosting, WordPress.org Plugin Directory


메타데이터
post_id
caa07ac073f5
slug
how-to-check-your-wordpress-with-essential-plugin-backdoor-with-bash-script-solution-caa07ac073f5
url
https://medium.com/@andreatadioli/how-to-check-your-wordpress-with-essential-plugin-backdoor-with-bash-script-solution-caa07ac073f5
canonical_url
https://medium.com/@andreatadioli/how-to-check-your-wordpress-with-essential-plugin-backdoor-with-bash-script-solution-caa07ac073f5
author_url
https://medium.com/@andreatadioli
status
ok
fetched_at
2026-06-09 15:37:30