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

Discovery Date

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 associated with the vulnerability as mentioned in technical details below. The files are produit_details.php, fonctions.php and configuration.inc.php. This section will explain the details through the simplest point in a way.


    produit_details.php

    Figure 1: produit_details.php

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

  • id parameter without sanitization

    Figure 2: id parameter without sanitization

  • 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()

  • get_product_infos function

    Figure 3: get_product_infos function

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

  • file fonctions.php

    Figure 4: file 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

  • get_filter_site_cond function

    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'

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

  • get_filter_site_cond

    Figure 6: get_filter_site_cond

  • 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).

  • $GLOBALS['site_id'] = 1

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

    Figure 7 shows the value of $site_id which is 1


    SQL query

    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.

  • Then, 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 is 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 a 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)


  • Delay in server response time per request respectively

    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.

Vendor Contact Timeline:

2021-07-10: Contact 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 releases security patches available on their website.

2021-07-26: Public release of security advisory

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