Unauthenticated Blind SQL Injection Vulnerability In PEEL Shopping (CVE-2021-37593)

NetbyteSEC Security Advisory - Unauthenticated Blind SQL Injection vulnerability In PEEL Shopping

Title: Unauthenticated Blind SQL Injection vulnerability In PEEL Shopping
Advisory ID:
NBS-2021-0001
Product:
PEEL Shopping
Vulnerable Version:
9.4.0
Fixed Version:
9.4.0.1
CVE ID:
CVE-2021-37593
Homepage:
https://www.peel-shopping.com/
Date of Discovery:
10 July 2021
Author:
Mohammad Faisal Sammio | NetbyteSEC

 
Vendor/product description:

"PEEL SHOPPING is a free ecommerce CMS in PHP / MySQL, that is to say a a modern and safety management tool that lets you manage your product catalog, the text on your website and everything else from a single, simple and efficient administrative interface. Since 2004, PEEL brings innovation and reliability to the world of e-commerce by offering tailored solutions to create complete and simple online shops at suitable prices for everyone."

Source: https://www.peel-shopping.com/


Vulnerability overview:

PEEL Shopping version 9.4.0 allows remote SQL injection. A public user/guest (unauthenticated) can inject a malicious SQL query in order to affect the execution of predefined SQL commands. Upon a successful SQL injection attack, an attacker can read sensitive data from the database and possibly modify database data.

 

Technical details:

There are three (3) files that associated to the vulnerability as mentioned in technical details below. The files are produit_details.php , fonctions.php and configuration.inc.php

 

Figure 1: file - achat/produit_details.php

line 22 - product_infos initialized an array() function to hold product info values 

 

Figure 2: file - achat/produit_details.php

line 55 - product_infos request input (user-controlled) via id parameter without being sanitized to be passed into arguments of get_product_infos() function.

**Since id is a type of integer, the proper sanitization method would be intval()


Figure 3: get_product_infos function

line 8014 - get_product_infos() function used to retrieve raw product information, where the argument $where is holding id value that being passed from var product_infos in (line 55, figure 2)

 

Figure 4: file - lib/fonctions/fonctions.php

line 8091 - check if $where is an array or not - return False

line 8093 - check if $where IS NOT number or a numeric string - return False 

line 8095 - else,  set $sql_cond_array[] = p.id = '$id'

line 8098 - Based on (line 8014, figure 3) the $filter_site_cond is TRUE, so $sql_cond_array will having get_filter_site_cond() function passing 4 arguments as stated in figure 4


Figure 5: get_filter_site_cond function

line 5553 - The $table_technical_code is storing 'produits' as its value (refer line 8099, figure 4), while $table_alias as 'p'

line 5554 - Since $table_technical_code == 'produits' which is NOT EMPTY, then $field will be 'site_id'


Figure 6: get_filter_site_cond function snippet

line 5637 - The $exclude_public_items is FALSE (refer line 5553, figure 5), else go to line 5645 

line 5645 - In short, $use_set is FALSE,  so $cond_array[] will be p.site_id IN ('0','1') - where $prefix = p. , $field = site_id  and $site_id = '1' (refer line 216, figure 7).

Figure 7: $GLOBALS['site_id'] = 1

Figure 7 shows the value of $site_id which is 1

 

Figure 8: SQL query

line 8104 - For now, the sql query will be ( SELECT p.* FROM peel_produits p WHERE p.id = '$id'p.site_id IN ('0','1') ORDER BY $order_by LIMIT $limit ) where $sql_fields = 'p.*'

line 8107 - There is an implode() function that will join array elements with a string of  " AND ". As we know, $sql_cond_array is storing p.id = '$id'p.site_id IN ('0','1') as its value. 

The output after implode() will be p.id = '$id' AND p.site_id IN ('0','1')

Since $order_by = null and $limit = 1 (refer line 8014, figure 3),

The final query will be :

( SELECT p.* FROM peel_produits p WHERE p.id = '$id' AND p.site_id IN ('0','1') LIMIT 1 )

 

For example:

Payload: '12' OR (SELECT * FROM (SELECT(SLEEP(5)))NBSX)

will work in the query as "WHERE" clause is the injection point:

( SELECT p.* FROM peel_produits p WHERE p.id = '12' OR (SELECT * FROM (SELECT(SLEEP(5)))NBSX) AND p.site_id IN ('0','1') LIMIT 1 )

When the query executed, it will select all data from table peel_produits by id equal to 12 and it will sleep for 5 seconds before showing the data.

 

Proof Of Concept:

 
The following concept could be used to perform blind SQL injection attack:
 
METHOD : GET
PARAMETER : id
PAYLOAD : (SELECT * FROM (SELECT(SLEEP(5)))NBSX)
URL : http://$HOST/achat/produit_details.php?id=[SQL-INJECTION] 

As a proof of concept for exploiting the blind SQL injection, requesting the following URL will cause a time delay.

http://$HOST/achat/produit_details.php?id=(SELECT * FROM (SELECT(SLEEP(5)))NBSX)

Figure 9: Delay in server response time per request respectively

 

Tested Versions:  

The vulnerability has been verified to exist in the PEEL Shopping version 9.4.0. It was found in this version, which was updated and released below a week just prior to the discovery.


Solution:
 

Update to the latest version 9.4.0.1 on their website.

Link: https://www.peel-shopping.com/modules/telechargement/telecharger.php?id=7

Vendor Contact Timeline:

2021-07-10: Contacting vendor through email.
2021-07-12: Request update from vendor, sending advisory draft and proof of concept.
2021-07-13: Vendor
response with acknowledgement and confirms security issue.
2021-07-14: Vendor release security patches available on their website.
2021-07-26: Public release of security advisory