Blocking more WordPress xmlrpc.php attacks

Over the last few days, we’ve been tracking an ever-increasing distributed attack on the WordPress xmlrpc.php service.

We’ve previously seen and blocked attacks on this file that tried to post spam comments or act as a denial of service amplifier, but this attack is different: it tries to guess WordPress usernames and passwords.

As a result, we’ve applied more aggressive blocking than usual to the attack. It’s remotely possible that the blocking could cause legitimate third-party WordPress “apps” and services to be unable to access your blog (although it can’t cause problems when just visiting WordPress in a normal Web browser); don’t hesitate to contact us if you’re one of our customers having trouble.

Just so it’s clear, we’ve blocked this attack for all our hosting customers. But the rest of this post has some technical details that may help other people trying to do the same.

What does the attack look like?

The attackers are POSTing xmlrpc.php commands that look like this:

<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
  <methodName>wp.getUsersBlogs</methodName>
  <params>
   <param><value>username</value></param>
   <param><value>password</value></param>
  </params>
</methodCall>

wp.getUsersBlogs is intended to be used by remote apps and services that need to find which blogs a username can access. However, the attacker is using this feature to test whether the username and password are valid, which they can do because WordPress returns “Incorrect username or password” in the XML result if they’re wrong. (The attacker is presumably stockpiling a list of valid WordPress logins for later use.)

We’ve so far tracked more than 30,000 IP addresses involved in the botnet carrying out the attack, with more being added all the time, averaging a few hundred total hits per day per WordPress site. It’s a slow attack — most of the IP addresses involved are making less than one connection every two hours to our servers, and the same IP address rarely attacks the same site twice in one day — so we can’t block it with rate limiting. Instead, we’re blocking most requests that send the rare “wp.getUsersBlogs” command, then attempting to whitelist any legitimate attempts based on the HTTP User-Agent or IP address.

What can I do to prevent these attacks?

Choose a strong password. Update WordPress and your plugins as soon as updates are available. Use two factor authentication.

Doing just those three things will ensure that attacks like this have no effect on your site, whether your hosting company is able to block them or not.