Brute force attacks against WordPress have always been very common. In fact, Brute Force attacks against any CMS these days is a common occurrence, what is always interesting however are the tools employed to make it happen.
You create a website, because it’s super easy these days, publish the content and within a few weeks people try to repeatedly log in. These login attempts come from botnets, they are automated and their goal is simple “break into as many websites as they can by guessing their passwords.” Once they find one that matches, they take over of the site and use it to distribute malware, spam and similar activities.
Here is a small example, from our own honeypots, where we see hundreds of login attempts per day, trying various combinations:
user: admin, pass: admin user: admin, pass: 123456 user: admin, pass: 123123 user: admin, pass 112233 user: admin, pass: pass123 ..
The passwords may seem silly, but after going through the most common 200/300 dictionary passwords, they can get into many web sites.
Originally, these brute force attacks always happened via /wp-login.php attempts, lately however they are evolving and now leveraging the XMLRPC wp.getUsersBlogs method to guess as many passwords as they can. Using XMLRPC is faster and harder to be detected, explaining this change in tactics. This is not to be confused with our post back in March where we reported XMLRPC being used to DDOS websites, oh no, in this instance they are leveraging it to break into websites. Be sure to read up on the differences between Brute Force and Denial of Service attacks.
This attack is being made possible because many calls in the WordPress XMLRPC implementation required a username and password. It these attacks, we are seeing wp.getUsersBlogs being used (and very few times wp.getComments), but it could be other calls as well. If you provide a user and a password to them, it will reply back if the combination is correct or not:
<methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value> <string>admin</string></value></param> <param><value><string>112233</string></value></param></params> </methodCall>
In the example above, the attackers tried the user admin with the password 112233.
Large Scale brute force
To examine the scale of this attack, we went back through our logs to get a better sense for the scale of the attacks. The past couple of weeks have been interesting, the attacks have increased ten-fold with almost 2 million attempts since the beginning of July coming from 17,000 different source attacking IPs. Some days we were seeing almost 200k attempts.
The only reason these numbers are not higher is because we’re killing the logs after block attempts, so all you are seeing is the gradual increase in attacks, but not the complete picture. This is what makes this entire thing very scary for website owners.
Another interesting point about this attack is the user names being tried. Instead of relying only on “admin”, it tries to find the domain name and the real admin of the site and use it instead. These are the top user names tried:
179005 test 167147 admin 32030 sitedomain (domain modified to protect the innocent) 15850 sitedomain2 (domain modified to protect the innocent) 9590 realsiteadmin (user name modified to protect the innocent) 9564 realsiteadmin2 (user name modified ..)
So out of 2 million attempts, only 167k used the user name admin. That shows that just disabling the admin user name, does not help if the attackers can easily find out the real user. One small reason we no longer subscribe to the argument of removing the “Admin” user to be secure.
As for the passwords, they are using the most common passwords found in many dictionaries:
1dc13d admin 123123 admin1 admins 123456 12345678 7777777 letmein 121212 qweqwe iloveyou administrator holysh!t 55555 1q2w3e qwerty wordpress wpsite internet asdfghjkl 121314 lollipop killer pass lovers hello dragon admin123 office jerome fyfcnfcbz
Brute Force Protection
There are many ways to block brute force attacks. If you have a dedicated server, you can install OSSEC (open source) on it and let it automatically block the IP addresses that miss too many passwords. We automatically include brute force (password guessing) protection on our Website Firewall (CloudProxy), so if you are looking for a 1-click solution, you can leverage it.
There are obviously a number of application level tools (i.e., plugins) many will recommend within the WordPress ecosystem to help with Brute Force attacks. Here is the thing, none of the ones we tried will protect you from the XMLRPC calls, including our own plugin. It’s likely why we’re seeing the shift in attack methods. Blocking at the edge is going to be your preferred method until that gets fixed.