|
Gadget chains in Wordpress |
Exploiting an unserialization vulnerability in WordPress never was a small issue. Unlike other PHP frameworks, and until very recently, WordPress was not known for hosting gadget chains.
The first one was discovered 10 years ago, with a complex execution sequence.
Lately, the second one was discovered; its structure is quite complex too, and it has been patched pretty quickly.
It was soon followed by a third one that depends on the presence of the WooCommerce plugin that is, of course, not guaranteed.
During a recent intrusion, we faced a wild unserialize, and none of the above worked. Thus we decided to dig it up and discovered that a trivial chain had just been implemented in the core of WordPress. Let's take a look, starting with the history.
The first interesting gadget chain on WordPress was found and presented in 2013 on versions below 3.6.1.
It is triggered using the __toString PHP magic method of the WP_theme class. From this class, the execution flow finally execute the make_plural_form_function method from the translations module that evaluates a portion of code controlled by the user during the unserializing process.
This pivoting sequence is summarized in the schema below from Sam Thomas slides: https://fr.slideshare.net/_s_n_t/php-unserialization-vulnerabilities-what-are-we-missing.
This gadget chain is relatively difficult to find because of pivots and the interaction between each object class involved.
This gadget chain in WordPress code was described on October 13th, 2023, by the WPScan team in the following article : https://wpscan.com/blog/finding-a-rce-gadget-chain-in-wordpress-core.
This chain is also triggered using __toString PHP magic method of the WP_theme class. Then, from this class, the exploitation needed to pivot using the sequence summarized below:

This popchain is complex because of the number of pivots needed to execute the interesting final code portion. The serialized payload exploiting this popchain speaks for itself:

This exploitation payload is available in the phpggc tool as WordPress/RCE1. This exploitation vector has been patched by WordPress since version 6.3.2 and is no longer present in the latest releases.
The second exploitation chain in the WooCommerce plugin is clearly easier to understand. It is triggered using the WC_Log_Handler_File WooCommerce class destructor and pivots via the Requests_Utility_FilteredIterator WordPress class in order to execute a vulnerable portion of the code. This exploitation vector was patched in WordPress 5.5.2, and targets need WooCommerce plugin to be installed for it to work. This exploitation payload is available in the phpggc tool as WordPress/P/WooCommerce/RCE1 and WordPress/P/WooCommerce/RCE2.
To sum up, only complex gadget chains were present in WordPress, another easier to find and to understand was available if the WooCommerce plugin was installed, and none of them is available in the latest versions (6.3.2, 6.4 and 6.4.1). Then, we started looking for gadget chains in WordPress and we found the simplest one.
WordPress defined in versions 6.4+ an internal class WP_HTML_Token used by the HTML processor during HTML parsing for referring to tokens in the input HTML string.
This class is defined in wp-includes/html-api/class-wp-html-token.php and implements a __destruct magic method that directly calls call_user_func method on the class variables without any pivot as shown below:

The on_destroy and bookmark_name attributes are controlled during the unserializing process, which makes the exploitation quite trivial. The payload looks like:

Fortunately for us, this class is loaded by the WordPress class loader in wp-settings.php. This makes the class WP_HTML_Token loaded and available in plugins and themes:
This exploitation vector is now available in the phpggc tool as WordPress/RCE2. Sometimes, simple exploitation vectors can be found in source code even in major projects such as WordPress. For now, the only version of WordPress that doesn't have a known gadget chain is 6.3.2.
Maxime Rinaudo est le co-fondateur de Fenrisk ainsi que l'un de ses experts en sécurité. Il est également passionné par la sécurité des applications web. Après avoir travaillé dix années au sein du Ministère des armées et 3 ans en tant que consultant à Paris, Maxime à décidé de rejoindre Julien dans son aventure afin de partager leur vision de la sécurité offensive.