In WordPress Hacked: Security Steps Take II, I wrote about the tools and steps to take to secure your WordPress installation. The current steps to take are the same. The tools, however, have changed significantly. Even as the steps changed from WordPress Hacked: Security Steps, now we look at the tools once more. I will reiterate the steps at the end of the post for completeness. However, let us begin by examining the tools. I have removed quite a few from my installs that I had previously recommended, and I will explain why below.
- All In One WP Security: This is a new and very welcome addition. Currently, the security scale is from 0 to 460 points, with all of the basics covered quite well indeed. There are settings to add captchas and modify .htaccess, and many other things that WP Security used to recommend but that now happen as part of the configuration. The file monitoring is also very good. In essence, this one plugin could be the one to start with for all basic WordPress security needs. I have augmented it with many of the following. The malware scanner, however, requires you to have an account. Since I already have one with Wordfence, I did not enable this functionality.
- SF Author URL Control: Rename the author page for your administrative user to something else. This is important, as you do not want your administrator user showing up as an author. That would just help out the hackers.
- Query Strings Remover: Removes version numbers from the CSS and JS scripts included by plugins and WordPress. These versions can be used to aid in hack attempts.
- WP Security Audit Log: This plugin logs all administrator, contributor, and below access within your blog. It’s a good way to determine what is going on, but be careful about how long you keep the logs around, as they could cause performance issues.
- Remove—Ultimate Security Checker: This is no longer a part of my install, as it has a serious issue. The plugin is unfinished and causes the options database to expand a row. That row eats up all memory and will slow down your site to a crawl. This happens only when folks log in, however. So, if you do not allow logins, the plugin is still fine. I edited the plugin to remove the issue, but I still would rather not use a plugin that is unfinished.
- Remove—Remote XMLRPC Pingback Ping: I used to use this plugin, but All In One WP Security now handles this for you.
- Clean Options: Go through all your options and remove any orphaned and unused options while also inspecting the options for malware. Not only will this clean up your current options, but it will also speed up WordPress.
- WordPress File Monitor Plus: This is the most important plugin. Configure it to run every day or more often, so that you can get a list of changes to your WordPress files. If anything changes, inspect immediately for malware. If anything is added to your list of WordPress files, it could be malware. Simply look at the files for base64 encoded data that looks cryptic and not like plain PHP code. I then inspect my Apache log files to determine who perpetrated the attacks, if possible, and block that from happening again using firewall rules. I have seen things pop in that show this does not pick up everything, however.
- Remove—WordPress Firewall 2: This adds some important but basic request verification against well known attack vectors but can also be bypassed. Wordfence also provides some of this functionality. As does All in One WP Security.
- Block Bad Queries: A plugin that will block malicious URL requests. I added more checks into the array it uses:
eval\(. These were added so that the Ultimate Security Checker rule would pass (if you are using that plugin). In addition, I changed the 403 Forbidden to redirect to the antecedent page.
- WP Crontrol: Provides a way to inspect those cron jobs WordPress requires to work. Lets you ensure there are only expected jobs in the list.
- Register Plus Redux, or some other registration functionality that requires users to click on a verification link. While it does not alleviate all comment/user hack attempts, it will remove quite a few spammers.
- WangGuard: Provides a way to look at your existing users to determine if they are spam users or in general unacceptable users per their network. Since logged-in users get more privileges, this could be a way in.
- WordFence: Provides a way to scan your site’s files, users, plugins, and themes against well-known good copies of the files. The known good copies reside on the Wordfence cloud. This has found a few minor elements on my site as well as discovering a few users with weak passwords.
- All others previously mentioned have been removed as they either are not working or have been replaced by one of the above plugins.
There are also a few .htaccess changes to the system to disable any XML-RPC communication, as it is a well-known attack path. The following code will deny all access to xmlrpc.php, the culprit. This is mitigated by All In One WP Security as well.
<Files xmlrpc.php> Order allow,deny Deny from all </Files>
If you detect an attack, you can use Exploit Scanner as your main tool to help find and eradicate it. You start with a fresh install of WordPress and the plugins. Then, you use Exploit Scanner with the appropriate hash file (even if you use one self-generated from a new download from wordpress.org). Anything else that looks suspicious you should look into and remove or edit as appropriate. I have found attack files in the oddest places. This is where the WordPress File Monitoring Plus plugin comes in handy. However, since most sites are not static, you really need to know which files are part of your plugins and which are not.
Wordfence also comes in very handy at this point to tell you if any plugin or base file has changed. Unfortunately, it does not tell you if any new files have been added that also contain hacks or attack vectors. This would be a nice addition.
I also use the Incapsula service as a CDN, which acts as a WAF for WordPress. It has caught and reported on many hack attempts.
Lastly, I still use New Relic as an early warning system for security issues within my site. It is helpful not only for security, but also for programming and plugin performance issues.
As promised, following are the rules I use to clean things up.
I have copied over my previous rules and added a few more.
- Make a backup of your database.
- Get a complete list of your existing themes and plugins.
- Download the latest WordPress ZIP file.
- Disable your existing WordPress installation (copy index.php to some other name).
- Move your old WordPress install from /usr/share/wordpress to /usr/share/wordpress.old.
- Make a new /usr/share/wordpress directory and install the latest WordPress into this directory.
- Restore your existing database.
- Use the default theme.
- Compare the Exploit-DB for WordPress against your list of plugins and themes (do not use any on the Exploit-DB).
- Search Google for specific 0-day attacks against your version of WordPress. If any exist, patch them as explained.
- Reinstall your theme if not on the Exploit-DB list.
- Reinstall your plugins if not on the Exploit-DB list. If you cannot find your plugins because they have gone the way of the dodo and become unavailable, then inspect every file for any form of malware and then copy from your “hacked” backup directory. If you do not know what malware looks like, then get a professional to help. Alternatively, find a new plugin that performs the same actions. Also, remember that some plugins, like Simple::Press and cForms, are not in the WordPress repository, and you should get modern versions of them. (Actually, cForms is no longer supported, maintained, or updated, so find an alternative plugin!)
- Change your Administrator and Editor passwords to a > 16-character pass phrase.
- Replace your NONCE salts within your wp-config.php file by getting a new set from https://api.wordpress.org/secret-key/1.1/salt/.
- Ensure no files or directories are world or group writable.
- Remove any unused themes and plugins (they can still be attack vectors even when not activated).
- Clear any cache files in wp-content/cache/* or other location.
- Change the permissions on /index.php to be non-writable (chmod ugo-w index.php).
- Change the permissions on /wp-config.php (or wherever you store it) to be non-writable (chmod ugo-w wp-config.php).
- Properly configure .htaccess to disallow direct access to wp-admin directory. In many cases, using mod_rewrite is sufficient to redirect access to /index.php.
- Remove readme.html and wp-admin/install.php after installing or reinstalling WordPress. No one needs to know your WordPress version or to access the installer.
- Use Exploit Scanner to help find malware and remove it. Periodically run a scan to find new files with possible malware.
Request for Action
I like to keep this post up to date, so please let me know what you use for security on your WordPress site. How do you detect malware? What plugins do you use and why?
Edward L. Haletky, aka Texiwill, is an author, analyst, developer, technologist, and business owner. Edward owns AstroArch Consulting, Inc., providing virtualization, security, network consulting and development and TVP Strategy where he is also an Analyst. Edward is the Moderator and Host of the Virtualization Security Podcast as well as a guru and moderator for the VMware Communities Forums, providing answers to security and configuration questions. Edward is working on new books on Virtualization.