WordPress xmlrpc.php Brute Force Attacks

The WordPress XML-RPC page is located at: site.com/xmlrpc.php
WordPress XML-RPC is pretty new way to guess the password. The trick here is that you can use 500 tries in one request.
One of the hidden features of XML-RPC is that you can use the system.multicall method to execute multiple commands inside of a single HTTP request. That means that the attacker can send 500 pairs of user/password to get credentials for your website.

A typical XML-RPC brute force request looks like this:

{methodCall}{methodName}system.multicall{/methodName}
{member}{name}methodName{/name}{value}{string}wp.getCategories{/string}{/value}{/member}
{member}{name}params{/name}{value}{array}{data}
{value}{string}{/string}{/value}{value}{string}admin{/string}{/value}{value}{string}demo123{/string}{/value}
..
{member}{name}methodName{/name}{value}{string}wp.getCategories{/string}{/value}{/member}
{member}{name}params{/name}{value}{array}{data}
{value}{string}admin{/string}{/value}
{value}{string}site.com{/string}{/value}
…

WordPress (xmlrpc) responds if any of the user/pass combinations used were successful (in this example, he tried the admin/demo123 and admin/site.com password combos):
[{‘faultCode’: 403, ‘faultString’: ‘Incorrect username or password.‘}, {‘faultCode’: 403, ‘faultString’: ‘Incorrect username or password.‘}, {‘faultCode’: 403, ‘faultString’: ‘Incorrect username or password.’}, {‘faultCode’: 403, ‘faultString’: ‘Incorrect username or password.’}, {‘faultCode’: 403, ‘faultString’: …
[[{‘url’: ‘http://site.com/wordpress/’, ‘isAdmin’: True, ‘blogid’: ‘1’, ‘xmlrpc’: ‘http://site.com/wordpress/xmlrpc.php’, ‘blogName’: ‘wpxxx’}]]]

The list of other methods that require authentication:
wp.getUsersBlogs, wp.newPost, wp.editPost, wp.deletePost, wp.getPost, wp.getPosts, wp.newTerm, wp.editTerm, wp.deleteTerm, wp.getTerm, wp.getTerms, wp.getTaxonomy, wp.getTaxonomies, wp.getUser, wp.getUsers, wp.getProfile, wp.editProfile, wp.getPage, wp.getPages, wp.newPage, wp.deletePage, wp.editPage, wp.getPageList, wp.getAuthors, wp.getTags, wp.newCategory, wp.deleteCategory, wp.suggestCategories, wp.getComment, wp.getComments, wp.deleteComment, wp.editComment, wp.newComment, wp.getCommentStatusList, wp.getCommentCount, wp.getPostStatusList, wp.getPageStatusList, wp.getPageTemplates, wp.getOptions, wp.setOptions, wp.getMediaItem, wp.getMediaLibrary, wp.getPostFormats, wp.getPostType, wp.getPostTypes, wp.getRevisions, wp.restoreRevision, blogger.getUsersBlogs, blogger.getUserInfo, blogger.getPost, blogger.getRecentPosts, blogger.newPost, blogger.editPost, blogger.deletePost, mw.newPost, mw.editPost, mw.getPost, mw.getRecentPosts, mw.getCategories, mw.newMediaObject, mt.getRecentPostTitles, mt.getPostCategories, mt.setPostCategories

You may protect your website by adding htaccess redirect:
Redirect 301 /xmlrpc.php http://www.google.com/
This may break some plugins which rely on XML-RPC feature (like Jetpack).

I created the Silver-Bullet Pro plugin which can protect xmlrpc.php file via Settings page. Plugin adds htaccess redirect for xmlrpc.php page for not loading WordPress on every brute force request.

Leave a Reply

Your email address will not be published. Required fields are marked *