I spent some time today on a WordPress site that was undergoing an xmlrpc.php attack. This is the file that other websites ping to notify of trackbacks on a post on your site. However, there is a fairly easily exploitable vulnerability in the concept that hackers are using to DDOS sites.
There’s a good post on Acutenix which describes the four ways this vulnerability is exploited:
- WordPress is trying to resolve the Source URL and will return different error messages if the Source URL exists (host exists) or not. This can be abused by attackers to try to guess hosts inside the internal network. The attackers can use URLs like http://subversion/ or http://bugzilla/or http://dev/to see if these hosts exist in the internal network.
- If the Source URL is resolved, WordPress will try to connect to the port specified in the URL. Therefore, if an attacker will use a URL like http://subversion:22/, WordPress will try to connect to the host subversion on port 22. The responses are different if the port is open or closed. Therefore, this functionality can be used to port scan hosts inside the internal network.
- This can also be used for distributed DOS (Denial of Service) attacks. An attacker can contact a large number of blogs and ask them to pingback a target URL. All of these blogs will attack the target URL.
- From the tests I’ve carried out, I’ve seen that WordPress is also supporting URLs with credentials. So, an attacker can use a URL like http://admin:firstname.lastname@example.org/changeDNS.asp?newDNS=aaaa to reconfigure the internal router.
What makes all this interesting is that since WordPress 3.5, users cannot disable XMLRPC through the WordPress admin interface. Previously, this was possible, but now the workaround is slightly more tedious.
There were fairly many different ways to mitigate this. The most common was to rename the file. However, if your WordPress is correctly setup – it will begin returning 404 -pages, which isn’t really solving the problem, it’s just moving it forwards. PHP will still need to parse those pages.
You want to stop it before it gets to Apache for processing, so I simply added the following to my .htaccess -file in the root of WordPress:
Deny from all
This was the single most successful way to mitigate the attack and lower the loads on my server. Do let me know if you’ve come across other ways to solve this. It seems like it’s becoming a major source of headaches by the amount of articles found online.