Blog post

A Salesmans Code Execution: PrestaShop 1.7.2.4

Robin Peraglie photo

Robin Peraglie

Vulnerability Researcher

Date

  • Security
Image shows various elements of code security, languages and bugs

The Impact 

With more than 270,000 running instances, PrestaShop it is one of the top 10 most used content management systems in the Web. Additionally to the classical software download, PrestaShop Ready offers to rent an online shop and to get administrative access to pre-hosted PrestaShop instances. From the perspective of attackers these e-commerce systems are very attractive targets because thousands of customers enter sensitive payment information.

The security bug is located in the orders section of the PrestaShops backend which requires access privileges for a SalesmanLogistician, or Admin account. For all of these three user roles, the read permission to the orders section is enabled by default. This is the only requirement for exploitation.

Matching this requirement an attacker can turn a PHP Object Injection vulnerability into a remote code execution vulnerability that allows to perform further attacks and to steal sensitive data. The attack is especially critical for PrestaShop Ready as an adversary can meet the requirement by setting up a free PrestaShop Ready trial account and potentially execute the exploit against the PrestaShop Ready cloud.


The Vulnerability

PrestaShop uses the PHP function unserialize() with user input which is a known bad practice and a security risk. This introduces PHP object injection vulnerabilities. But in order to prevent these issues, PrestaShop added a wrapper method unSerialize() to its code base that tries to prevent malicious injections.

classes/Tools.php

3359    public static function unSerialize($serialized, $object = false)
3360    {
3361        if (is_string($serialized) && (strpos($serialized, 'O:') === false
3362	        || !preg_match('/(^|;|{|})O:[0-9]+:"/', $serialized)) && !$object
3363	        || $object) {
3364            return @unserialize($serialized);
3365        }
3366
3367        return false;
3368    }

Based on the second argument $object of this method, an additional security check is added (enabled per default). This additional security check considers any $serialized input as harmless if it does not match a specific pattern. The regular expression O:[0-9]+:" in line 3362 tries to detect if an attacker injected serialized objects which is a known exploitation technique.

However, this black-list security approach is insufficient since not all serialized object strings match this regular expression. Similar to Challenge 11 of our PHP Advent Calendar 2017, it is possible to bypass the validation check and to inject any serialized object. This can be achieved by adding + characters to the length values of the serialized object string. These + characters will not break the unserialize() result but will bypass the matching pattern of the regular expression. The following table illustrates this effect:

As a result, an attacker can inject nested objects in their serialized format and obfuscate the true malicious nature from the regular expression. The then deserialized PHP objects can force PHP to execute code in specific magic methods. You can find out more about this attack technique in our previous blog post.

The Payload

Finding a PHP object chain can be a tedious and time-consuming process as the code base has to be searched for suitable classes which expose methods that can be used for exploitation. Often though, Composer is used to adding many dependencies to the code base although only a small fraction of their code is actually used. In big applications like PrestaShop this results in a large attack surface for crafting a PHP object chain. Even better, RIPS is able to automatically scan the code base for possible exploit chains when a PHP object injection was found. It was possible to leverage parts of the Monolog library to craft a chain that in the end executes arbitrary code on the PrestaShop server. We refrain from releasing a working exploit at this moment.

Timeline

DateWhat
2018/02/09Provided vulnerability details and PoC to vendor
2018/02/13Vendor confirmed security issue (https://github.com/PrestaShop/PrestaShop/pull/8755/)
2018/02/26Vendor released patch (https://build.prestashop.com/news/prestashop-1-7-2-5-maintenance-release/)

Summary

In this post we analyzed a critical security vulnerability in the popular PrestaShop e-commerce solution. It could be exploited directly by setting up a free trial account of PrestaShop Ready or by malicious PrestaShop users with a Salesman role. Successful exploitation leads to the remote execution of arbitrary system commands and to the breach of sensitive payment information of customers. It is highly recommended to update your shop installation. We would like to thank the PrestaShop team for the professional communication and the very fast release of a patch.