Analyzing and Exploiting CVE-2020–15160 | PrestaShop Blind Sql Injection | AWAE/OSWE Prep
By: Vanshal Gaur
Tags: PHP, Infosec, Code Review, Sql Injection, Hacking

There was No public exploit available for this CVE so i thought why not give it a try, though Understanding the code flow and Exploiting this took me quite a lot time, at last all of it seems straightforward.

Exploit script for this is CVE, now available at exploit-db

CVE Details: CVE-2020–15160 (Basic user authentication is required)

PrestaShop from version 1.7.5.0 and before version 1.7.6.8 is vulnerable to a blind SQL Injection attack in the Catalog Product edition page with location parameter. The problem is fixed in 1.7.6.8

Setting up the vulnerable docker:

I had some problem installing the vulnerable version, i tried on kali,ubuntu but i was getting some errors, long story short i tried installing multiple version and 1.7.6.7 installed successfully without any issues:

Installing: https://hub.docker.com/r/prestashop/prestashop

docker network create prestashop-net docker run -ti --name mysql_z --network prestashop-net -e MYSQL_ROOT_PASSWORD=admin -p 3307:3306 -d mysql:5.7 docker run -ti --name prestashop_z --network prestashop-net -e DB_SERVER=mysql_z -p 8080:80 -d prestashop/prestashop:1.7.6.7

Access Docker shell by:

docker exec -it prestashop_z /bin/bash

docker exec -it mysql_z /bin/bash

Prestashop is successfully deployed and running on port localhost:8080

Complete the installation from localhost:8080

Make Sure to give mysql_z as “Database server address” when asked during installation

I spent good amount of time understanding the code flow of application since its using symfony framework which i didn’t know about before this.

Understanding the Code

As mentioned in CVE description: Catalog Product edition page with location parameter is vulnerable so first lets find this location parameter

So this might be a user controlled get or post parameter:

grep -ir -F “\$_GET[‘location’]” --color

grep -ir -F “\$_POST[‘location’]” --color

src/PrestaShopBundle/Controller/Admin/ProductController.php

Stepping into the code :

function named processLocation is called with the user supplied location parameter

setLocation function is called from StockAvailable Class

classes/stock/StockAvailable.php

Okay so we finally found what’s happening with location parameter:

If the existing_id is > 0 which it always is(I confirmed with debugging) then the update function will construct the sql query with the given parameters and execute it.

Okay! but How to send payload though location parameter?

As mentioned in CVE description: Catalog Product edition page

There’s a “go to catalog” option in that page.

Intercepting the request:

Create Or edit Product with Combinations selected as Simple Product -> Click Go to Catalog and intercept that request. By default the location parameter(form[step3][location]) is set to null, change that to something eg: TESTINGPARAMETER and send that request

I did enable mysql log in mysql_z docker and found the query executing is:()

Injecting the payload: 0' #

This will change the location column for every id_product to 0 everything else will be commented:

0' # (URL ENCODE THIS)

Query executed will be:

UPDATE `ps_stock_available` SET `location` = '0' #' WHERE id_product = 22 AND id_shop = 1 AND id_shop_group = 0 Everything after # will be commented in the query.

Burp POST req

Exploiting Blind Sql Injection:

Limitations:

Cannot use ; and = in the injection query

Payload: 0'|(ascii(substr(user(),1,1)) regexp 114)#

Payload Explanation:

The idea is to set location to 0, or 1 if the supplied condition matches.

substr will retrieve the first character of the output of user() function and ascii will convert it and then regexp will match if the first retrieved character is 114 which decodes to “r”

regexp is a very handy mysql operator we use it to solve our equals sign restriction

Doing this manual is not quite possible so i wrote a python script to retrieve the data.

This script is also available at exploit-db.

The script logins the application, fetch the tokens required for request and loop through vulnerable parameter with injection query and check for location to be 1 in every iteration. if the location is 1 it means that the payload returns to be true, so the script give us the output character of the sql query we injected.