Recently, a new brute force attack method for WordPress instances was identified by Sucuri. This latest technique allows attackers to try a large number of WordPress username and password login combinations in a single HTTP request.
The vulnerability can easily be abused by a simple script to try a significant number of username and password combinations with a relatively small number of HTTP requests. The following diagram shows a 4-fold increase in login attempts to HTTP requests, but this can trivially be expanded to a thousand logins.
This form of brute force attack is harder to detect, since you won’t necessarily see a flood of requests. Fortunately, all CloudFlare paid customers have the option to enable a Web Application Firewall ruleset to stop this new attack method.
What is XML-RPC?
To understand the vulnerability, it’s important to understand the basics of the XML remote procedure protocol (XML-RPC).
XML-RPC uses XML encoding over HTTP to provide a remote procedure call protocol. It’s commonly used to execute various functions in a WordPress instance for APIs and other automated tasks. Requests that modify, manipulate, or view data using XML-RPC require user credentials with sufficient permissions.
Here is an example that requests a list of the user’s blogs:
<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param>
<value>
<string>admin</string>
</value>
</param>
<param>
<value>
<string>password123</string>
</value>
</param>
</params>
</methodCall>
The server responds with an XML message containing the requested information. The isAdmin
name-value pair tells us our credentials were correct:
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<params>
<param>
<value>
<array><data>
<value><struct>
<member>
<name>isAdmin</name>
<value><boolean>1</boolean></value>
</member>
<member>
<name>url</name>
<value><string>http://example.com/</string></value>
</member>
<member>
<name>blogid</name>
<value><string>1</string></value>
</member>
<member>
<name>blogName</name>
<value><string>testing</string></value>
</member>
<member>
<name>xmlrpc</name>
<value><string>http://example.com/xmlrpc.php</string></value>
</member>
</struct></value>
</data></array>
</value>
</param>
</params>
</methodResponse>
As shown in this request, you must provide proper authentication to get a successful response. You can, in theory, create a script that tries different combinations of the username and password, but that is a noisy option that isn’t very effective and is easily detected (the server logs would show a flood of failed login attempts).
This is where the system.multicall
functionality comes into play. You can run multiple methods with a single HTTP request. This is useful for mass editing blogs or deleting large numbers of comments, etc. Any method that requires authentication can be abused to brute force credentials. Here is what a sample XML system.multicall
payload would look like:
<?xml version="1.0"?>
<methodCall>
<methodName>system.multicall</methodName>
<params>
<param><value><array><data>
<value><struct>
<member>
<name>methodName</name>
<value><string>wp.getUsersBlogs</string></value>
</member>
<member>
<name>params</name><value><array><data>
<value><array><data>
<value><string>admin</string></value>
<value><string>password</string></value>
</data></array></value>
</data></array></value>
</member>
</struct></value>
<value><struct>
<member>
<name>methodName</name>
<value><string>wp.getUsersBlogs</string></value>
</member>
<member>
<name>params</name>
<value><array><data>
<value><array><data>
<value><string>admin</string></value>
<value><string>password</string></value>
</data></array></value>
</data></array></value>
</member>
</struct></value>
</data></array></value>
</param>
</params>
</methodCall>
As you can see, this can lead to very obvious abuse.
Exploitation
During testing, I was able to call the method wp.getUserBlogs
1,000 times in a single HTTP request (limited only by PHP memory issues). If a user creates a simple shell loop that executes one thousand times and runs a PHP script that crafts an HTTP request with one thousand method calls all requiring authentication, then that user would be able to try one million unique logins in a very short period of time.
This makes brute forcing the login very fast and can run down a pretty large wordlist in a short period of time. Also note that the wp.getUserBlogs
method isn’t the only RPC call requiring authentication. It’s possible to use any RPC method which requires authentication to attempt logins and brute force the Wordpress credentials.
CloudFlare Customers Are Protected
When using CloudFlare with a Pro level plan or higher, you have the ability to turn on the Web Application Firewall (WAF) and take advantage of the new WordPress ruleset I created to mitigate this attack—all without any major interaction or supervision on your end.
Our WAF works by checking HTTP requests for consistencies that line up with known attacks and malicious activities. If a request does appear to be malicious, we drop it at the edge so it never even reaches the customer’s origin server.
To enable the rule, navigate to your CloudFlare Firewall dashboard, and reference the rule named "Blocks amplified brute force attempts to xmlrpc.php" with the rule ID WP0018.
That’s all there is to it. Now you are protected from the new WordPress XML-RPC brute force amplification attack.
The Manual Solution
Another way to mitigate this attack is by disabling the ability to call thesystem.multicall
method in your Wordpress installation by editing yourfunctions.php
file. Adding the function mmx_remove_xmlrpc_methods()
will alleviate the problem, like so:
function mmx_remove_xmlrpc_methods( $methods ) {
unset( $methods['system.multicall'] );
return $methods;
}
add_filter( 'xmlrpc_methods', 'mmx_remove_xmlrpc_methods');
Final Thoughts
XML-RPC can be a useful tool for making changes to WordPress and other web applications; however, improper implementation of certain features can result in unintended consequences. Default-on methods like system.multicall
and pingback.ping
(we have a WAF rule for that one, too) are just a few examples of possible exploits.
Properly configuring the CloudFlare Web Application Firewall for your Internet facing properties will protect you from such attacks with no changes to your server configuration.