Contact Info
5 Rue Louis Dessard 95120, Ermont

Follow us

Gadgets chain in Wordpress

Gadgets chain in Wordpress

22 Nov 2023 By Maxime Rinaudo

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.

Brief history of WordPress gadget chains: The very first one

The first interesting gadget chain on WordPress was found and presented in 2013 on versions below 3.6.1.

It is triggered using __toString PHP magic method of the WP_theme class. From this class, the execution flow finally execute make_plural_form_function method from 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.

Brief history of WordPress gadget chains: RCE1

This gadget chain in WordPress code was described on october the 13th 2023 by 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 amount 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 tool phpggc as WordPress/RCE1. This exploitation vector has been patched by WordPress since version 6.3.2 and is no more available in latest releases.

Brief history of WordPress gadget chains: The WooCommerce chain

The second exploitation chain in WooCommerce plugin is clearly easier to understand. It is triggered using WC_Log_Handler_File WooCommerce class destructor and pivot via 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 but targets need WooCommerce plugin to be installed. This exploitation payload is available in the tool phpggc as WordPress/P/WooCommerce/RCE1 and WordPress/P/WooCommerce/RCE2.

Hidden in plain sight, the new one

To sum up, only complex gadget chains were present in WordPress, another easier to find and understand is available if the WooCommerce plugin is installed and none of them is available on 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:

on_destroy and bookmark_name attributes are controled 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 that makes the class WP_HTML_Token loaded and available in plugins and themes:


This exploitation vector is now available in the tool phpggc 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

Maxime Rinaudo

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.