It’s been two months since our disclosure of an Object Injection vulnerability affecting versions <2.3.3 of the Joomla! Hikashop extension. The vulnerability allowed an attacker to execute malicious code on a target website.

How Does Object Injection Work?

Object Injection occurs when raw user input is passed to an unserialize() function call. When this happens, someone with malicious intent can send a serialized instance of a class known in the current application’s context, ensuring that at least one of these class’s defined as magic methods will be executed at some point in the code.

The Culprit

The two points of interest here are lines 124 and 132. In this instance, the $infos variable is set to JRequest::getVar()‘s return value, this means it can either take $_GET['infos'] or $_POST['infos']‘s value. It then decodes $infos‘s content using base64_decode() and passes it to the unserialize() function.

Sucuri - Hikashop Vulnerability – Attack Vector

Sucuri – Hikashop Vulnerability – Attack Vector

With this information in hand, we set out to building a valid payload that would allow us to abuse the function in question. In our Proof of Concept (PoC) we set out to abuse the Joomla! 3.3.x classes and defined success by pulling the webservers /etc/passwd.

Building the Payload – Finding a Pivot

The first thing we need to do is control the applications’s execution order and we need to do it using the Joomla! classes magic methods. A popular one is PHP’s class destructor method, __destruct(), as it is automatically executed during the script’s shutdown sequence.

In this specific case, we chose JDatabaseDriverMysqli class’s destructor as it fit our needs: it allows us to call methods from any classes available.

It would call the disconnect() method:

Destruct function code snippet

Destruct function calls disconnect method

Which is designed to call every callback function within the $this->disconnectHandlers variable:

Disconnect function

Disconnect function

We prepare the attack by creating a modified version of the JDatabaseDriverMysqli class, allowing us to modify some the variable default values. More specifically, we need it to meet a few criteria so that its serialized counterpart, once unserialized by Hikashop, spawns an instance whose destructor will execute any function/method we feed it with.

To accomplish the above we need to:

  1. Ensure we set $this->connection to the boolean value “True” (otherwise we won’t get to the call_user_func_array() call)
  2. Fill $this->disconnectHandlers with an array containing either: