There is a very real, very large ongoing attack against WordPress sites. It has been going on for a while now, but it severely escalated last week.
While there is a lot of chatter about this situation around the web, I thought I should write this post for two reasons: 1) not everyone in our community follows all of the WordPress and tech news and 2) most of the coverage has been either extremely technical or very light on details and recommendations. My goal in this post is to not only inform you about what is happening but why it is happening and what you can do about it.
The details of the attack has been covered far and wide. Hostgator was one of the first big names to break the news about the attack with their Global WordPress Brute Force Flood post. The WordPress security team at Sucuri has as series of blog posts about the topic covering how to protect your site, the reality of the attacks, and the consequences of such attacks. Security blog Krebs on Security has a good post covering the topic in depth.
The short and simple explanation of what is happening is that one or more illegal botnets (a network of hundreds, thousands, or millions of compromised computers that are being exploited to perform attacks, send spam, etc) are being used to brute-force attack WordPress sites. The goal of a brute force attack is to try as many username and password combinations as possible in order to find valid login credentials. It’s as if someone was trying to guess the combination on a combination lock, but rather than being limited to a single guess every few seconds, they could make hundreds or thousands of guesses a second while never getting tired.
As described above, one or more botnets are being used to perform these attacks. While the actual goal of these attacks is unknown, it is safe to assume that the purpose of these attacks is to compromise more systems, thus increasing the size and strength of the botnets.
As you can see in a description of the types of attacks that botnets can execute, botnets can be used to shut down websites, compromise security of high security systems, be used to commit fraud, send spam, and perform a number of other illegal activities. The simple reality is that botnets are big business these days. In the interest of security of the internet as a whole, it is the responsibility of all of us that run websites to do our best to prevent our systems from being compromised and becoming part of the problem.
There are two threats to your sites during this attack: a threat from the login attempts and a threat if a login is successful.
Each time WordPress handles a login attempt, your server’s resources are being used. If the attack starts to send numerous login attempts a second, your site’s performance can suffer. Depending on your hosting, you might even have your service suspended due to the increased load your site is adding to the server. This last scenario is a worst case example and is very unlikely to happen, but it is still a possibility and is worth mentioning in order to clarify the potential severity of such attacks.
If the attacker is able to successfully guess the login to your site, then your entire site and server could be compromised. If the user has a role of Administrator, this opens up the ability for the attacker to modify anything on your site. They could add new files, modify existing files, add additional users in case the password of the compromised user is changed, inject malware into the output of your site, turn your hosting account into a spam bot, and anything else the attacker could possibly desire using a random server for.
The good news is that there is a pattern in these attacks. By finding patterns, intelligent solutions to protect against the attack can be created.
After reading numerous security postings about this issue and looking at my own logs on the attacks, it is clear that the vast majority of these attacks are focused on trying to figure out the password for the “admin” user. Looking at the stats for one of the sites that I’m watching, just shy of 99% of the login attempts have been for the “admin” user. The bulk of the other guesses are for usernames of “administrator” or “Admin”. There have also been a few that try using the main part of the domain name as the username. For example, it would try guessing “ithemes” if trying to log into the ithemes.com site.
Update: After posting this, the bots are now trying some additional usernames with some frequency. The new usernames being tried are “editor” and “moderator”. Each of these now account for more than 10% of the login attempts being tried. It would be a good idea to not have any users with a username of “admin”, “editor”, or “moderator” on your site. If you have any such users, the next section describes how to remove them.
There is also a clear patten in the passwords being guessed. This is natural as people have a very bad habit of choosing very weak passwords. Unfortunately, the things that are easy for us to remember are also quite easy to guess. Looking at the passwords being guessed over the past few days, the following passwords come out on top as the most frequently guessed ones:
As you can see, there is definitely a pattern of basic English words and easy to type letter or number sequences. The reason that these are being guessed frequently is that they are likely to work on the greatest number of sites. In other words, they are being guessed because people still use such passwords.
There are a massive number of computers that are taking part in this attack. Some reports show more than 90,000 unique IP addresses taking part in this attack. Just one of our sites has seen 246 unique IP addresses being used to make login attempts. This is the power of a botnet attack as the attack is literally coming from everywhere.
Brute force login attempts are by no means new. Such attack techniques have been used against WordPress sites for as long as WordPress has existed. In the past, I’ve recommended users install and activate the Login Lockdown plugin as it helps protect against brute force attacks. It protects the site by blocking login attempts by a specific IP once that IP has failed too many times in a row. Unfortunately, as the pattern section above shows, these attacks are coming from a huge range of IP addresses. Simply being able to block specific IP addresses after failed attempts will not protect a site against this botnet attack. This means that a different solution is needed.
Remove the admin Username
Looking again at the pattern details, the first thing that all WordPress site operators must do is remove the username “admin” from the site. By far, this is the biggest vulnerability that is being exploited in this attack. So, if you have a user with a username of “admin” on your site, it needs to be either removed or renamed ASAP.
The easiest way to rename the user is to replace it with a new user. This can be done in the following sequence of steps:
- Create a new user with the same role as the “admin” user. This is typically the Administrator role. You may have to use a different email address when creating this user as each user must have a unique email address.
- Log out.
- Log in as the new user.
- Delete the “admin” user.
- When asked what to do with the posts and links owned by the “admin” user, select the “Attribute all posts and links to” option, choose the new user from the drop down list, and click “Confirm Deletion”.
- Once the user is removed, you can change the new user’s email address if a different one was used to create it.
While there are plugins that allow you to change a user’s username and it is possible to rename the username in the database, I’ve always preferred this method. The primary benefit is that this method is very fast and easy. The secondary benefit is that I’ve seen some WordPress hack scripts that explicitly modify the database records for the user with an ID of 1. Since the “admin” user is likely to be the user with an ID of 1, deleting it means that these hack scripts can’t function. It’s not a hugely important thing, but it is nice to know that some of the simple scripts that are floating around out there will fail on sites that don’t have a user with an ID of 1.
Use a Better Password
I really debated if this should be first or second. The reality is that removing the “admin” username will almost certainly protect you from malicious logins from this attack. However, a bad password makes you very vulnerable to just about any other attack. If you have any users that have a password that is listed above or that have a password that is similar in simplicity to those listed above, go and change those passwords immediately.
The question of “how do I create a better password?” has endless answers. There is the classic go to XKCD comic Password Strength which shows the problem we’ve created by forming hard to remember yet relatively easily broken passwords rather than focusing on easy to remember yet very hard to break passwords. If you search around, you’re likely to find hundreds of different guides on how to create secure passwords.
The problem with most guides you’ll find is that they either help you create complicated short passwords that are supposedly easy to remember, such as “fl1r7“, or very long passwords such as “ComplekspasswordsRsafer2011.” The problem I have with these suggestions is that they are always unrealistic. Today I might find it easy to remember that I need to change every third letter to a number, but in just a week, I could be confused as to whether it was every second letter is a number or if every fourth letter is a number. In addition, really long passwords are 1) not easily remembered at all (sorry Randall Munroe of XKCD) and 2) are even more of a pain to type in all the time.
To compound this issue is that the biggest threat to your passwords is password reuse. If you use the same password all over the place, all it takes is for one of your accounts to be compromised in order for the attacker to gain access to nearly all your accounts. While it is very bad practice, many online services store passwords in plain text or with only very basic modification of the password. Over the past few years, there have been tons of reports of sites having their user database compromised and leaked on the net. Once attackers get these leaked login details, they quickly use the details to try to compromise accounts on other services. So, if you use the same password on twenty sites, a password leak on just one of those sites makes your accounts on all twenty sites vulnerable.
So, we need passwords that are 1) not short, 2) not simple, 3) simple to input repeatedly so we’re not tempted to violate the first and second rules, and 4) able to be unique for every site we use. There are all sorts of tricks I’ve seen to get past the fourth rule. The common one is to use the name of the site in the password, such as “password123youtube“. While this will indeed make the passwords unique to each site, all it would take is someone looking at the password to figure out the pattern and apply it to other sites. So, the fifth rule is 5) ensure that in following 1-4 that we don’t create passwords that can be easily guessed if someone sees the pattern.
While struggling with this myself a while ago in my quest to have better passwords, I found that we humans just aren’t good at this. To make good passwords, we basically need random noise turned into a decently-long sequence of characters. This is not something that we do well at.
The solution I ended up going with was LastPass. LastPass is a password service. It centrally manages all of your passwords and has tools to easily create very complex passwords. It even has browser integration features that allow you to have LastPass automatically fill in the login details for you (no typing required). LastPass also offers apps for mobile and tablet platforms and has a web interface in case you need the password and can’t get it any other way.
Using LastPass allows me to have extremely complex passwords that I could never remember and would hate to type in on every site I use. I vary the length of my passwords that it generates, but they are always more than 25 characters as long as the site allows it. 25+ characters of more or less random characters… Good luck brute force guessing that in my lifetime.
The key to using LastPass is having a good password to authenticate your user there. This is the only password you will need to remember; so make sure that it is a good one. Don’t do yourself the disservice of having your one weak password give full access to all your strong passwords.’
There are alternatives to LastPass. I don’t have personal experience with any of them, so I can’t give a recommendation. The ones that I’ve seen most often are:
- KeePass – An offline, cross-platform password manager. Basically, this is an encrypted local copy of your passwords as they aren’t stored on any server. I’ve seen people use Dropbox to allow their passwords to sync to different systems.
- 1Password – A paid password manager with option to sync to the cloud. I know at least one person in the office uses this software.
- Keeper – Seems to try to compete directly with LastPass in terms of feature set.
- RoboForm – Another service similar to LastPass.
Protect Against Performance Issues
Now that your site doesn’t have the “admin” user and your passwords are very difficult to guess, you are still left with the problem of bots constantly trying to log into your site. Solving this problem is probably one of the harder ones. Technically, the site is safe, but you don’t want your site’s performance to suffer just because some bots are hammering your server.
My first recommendation is to talk to your hosting company. I’ve seen a number of hosts suggest opening up a support ticket as they can help block some of the attack. I’m not sure exactly what methods these companies are using, but there are a variety available that could be quite effective.
If you are on a self-managed server or have a host that can’t help, I’d first look to see if your site is being hammered with requests. You can do this by looking at the access logs for your site. Simply look to see how often the wp-login.php page is being requested. If you have a very big community, then you might see a lot of requests for that page as just a normal part of site operation. If the number of requests is relatively-low (a few a minute or less), then I wouldn’t worry about taking any action. Such a low number of login attempts is unlikely to affect your site, and adding additional changes just runs the risk of damaging a functional site. If the number of requests is higher (especially if there are numerous requests each second), then I would pursue other options more seriously.
The easiest option to consider after talking to your hosting company is using CloudFlare. CloudFlare is a CDN service that also helps protect your site against attacks of this nature. In response to this situation, they posted details on how they handle such brute force attacks. I’ve used a free CloudFlare account for my personal site for the past few months. While I don’t know exactly how much traffic CloudFlare is blocking, I do see a very low number of requests to my site’s wp-login.php page. There is an official CloudFlare plugin. I don’t use it personally as I don’t make use of the caching feature of CloudFlare, so I can’t speak to the benefits offered by it.
Unfortunately, if your hosting company can’t help you and CloudFlare isn’t an option, the only remaining solutions are quite technical and may require root permissions on your server (something not available to shared or managed hosting accounts). If you don’t know much about server administration and are having issues with the attack hurting your site’s performance to consider moving to hosting that can protect you from the attacks. Make sure that you contact the potential new host beforehand to see if they are prepared to help protect your site from the attack.
The most prevalent technical solution is using ModSecurity rules on Apache to limit the login attempts. Of course, this requires that your server is running Apache and has ModSecurity available or you are able to install it.
Another popular solution is to password protect access to the wp-login.php file and wp-admin directory. A big benefit of this is that the requests won’t hit WordPress at all unless they are authorized, reducing the relative load of the attack to nearly 0.
Update Your wp-config.php Keys
The wp-config.php file contains a series of security keys. These keys are used for different authentication and security methods used by WordPress. The keys should be unique to each site. Unfortunately, old WordPress installs never had these set, leaving a potential security hole. Updating the keys is highly recommended to protect your site against a variety of different attacks.
Note that changing these will cause everyone to need to log in once again. This is a feature really as any compromised login will be invalidated.
What do you do if you think your site was compromised? Unfortunately, the only sure-fire solution is to more or less start over:
- Create a full backup of your site.
- Delete all the files on your site.
- Download a fresh copy of WordPress.
- Unzip the WordPress files.
- Upload the WordPress files to your server.
- Inspect the wp-config.php file from your backup to look for any suspicious code. Comparing the file to the wp-config-sample.php file in the newly downloaded WordPress files will help identify any issues.
- Copy the wp-config.php from your backup to the new site.
- Download fresh copies of your themes and plugins from the original source. Make sure you don’t download the files from random sites on the net as these frequently contain malware.
- Unzip the theme and plugin files.
- Upload the themes and plugins to the site.
- Run the site to verify that it functions.
- Delete any users that you do not recognize.
- Change the password of each user. This is important as it is possible that the attack changed passwords and would allow the attacker to compromise your site again. By resetting each users’ password, you ensure that the passwords are what you expect them to be. Of course, when you are doing this, make sure that you apply the above recommendations. Don’t leave an “admin” user and don’t use simple passwords.
- Go through the wp-content/uploads directory in your backup and copy the directories to the new server. Ensure that what you are copying are media files (images, audio, video, etc). If you find any PHP files, do not copy those to the server.
Yes, this is tedious, but it is the only way to be sure that modifications put in place by the attacker don’t remain. Even a single file or a single file modification that is left behind could cause your server to be compromised all over again.
You may wonder what this means if you multiple sites. Unfortunately, if you have a hosting account with a large number of sites, you have to treat the entire account as compromised. Limiting your focus to just one site on the account leaves you open to the possibility that other sites were modified.
Okay, the final heading is a bit contrived. It worked well up until now.
There isn’t such a thing as full-proof security. It simply doesn’t exist. That doesn’t mean that you should give up. Ignoring all security measures is just asking for trouble. However, going overboard on security is likely to be a waste of time. So, a balanced approach is what you should use.
I mentioned the Login Lockdown plugin earlier. While it won’t save you from this attack, it is definitely still recommended. Until WordPress gets some built-in brute force protection (hint, hint devs), running a plugin such as this one is highly recommended.
A hat tip to James McWhorter who points out in the comments that Login Lockdown has a “Lockout Invalid Usernames?” option. Enabling this option in the plugin’s settings will automatically block login attempts that use an invalid username. This could greatly help in protecting your site from this specific attack.
Some people have asked in comments and tweets about the age of the Login Lockdown plugin (since it does display a notice on its page). I have run the plugin for many years without issue, so I know from personal experience that it works well with current versions of WordPress, including multisite installs. While I could suggest other plugins that have similar features and do not have warnings about age, I recommend Login Lockdown since I can recommend it without reservation.
Follow the recommendations given in The Solution above on all of your sites. They help protect you against much more than just this attack.
Always keep your WordPress sites up to date, including plugins and themes. This is critical as security holes in older versions are found given enough time.
If you have a large number of WordPress sites, and they are becoming difficult to manage, consider using a multisite install to centralize many of your sites. This allows you to more easily keep WordPress and its themes and plugins updated. Another option is to use ManageWP which allows for management of multiple sites from a central location.
While the passwords you use to log into WordPress are important, the passwords to access your hosting account are just as important. If your FTP or cPanel password is easily guessed, you are still vulnerable. In addition, WordPress allows you to reset passwords by email, so if your email account is vulnerable, so is your site. After you finish improving the passwords for your sites, go and improve the passwords used for your hosting accounts and email.
One potential security issue many people don’t think about are the plugins and themes that aren’t in use. It may come as a surprise that inactive plugins and themes can still be used to compromise a site, but it is very true. The Timthumb exploit of a year and a half ago worked just as well with an inactive plugin or theme as an active one. So, rather than leaving a large set of deactivated plugins and themes on your site, back them up somewhere and delete them.
I hope that this information has been helpful. I really wasn’t sure if I should post this or not since so much has been said about it already. If you would like to see more posts of this nature in the future, please leave a comment saying what part of the post was most helpful to you.