From fbc588a4b6943147990d781f1ffea9e8f2f6c5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Mu=C3=B1oz?= Date: Tue, 31 Dec 2024 19:19:41 -0500 Subject: [PATCH] Reescrito a python --- README.md | 166 ++++++++--------- requirements.txt | 5 + sevo | 459 ----------------------------------------------- sevo.py | 299 ++++++++++++++++++++++++++++++ 4 files changed, 377 insertions(+), 552 deletions(-) create mode 100644 requirements.txt delete mode 100755 sevo create mode 100644 sevo.py diff --git a/README.md b/README.md index 2341401..445f241 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,70 @@ -# 🕵️‍♂️ SEVO - Security Email Validator OSINT v1.1.0 +# 🕵️‍♂️ SEVO - Security Email Validator OSINT v2.0.0 -![Version](https://img.shields.io/badge/version-1.1.0-blue.svg) +![Version](https://img.shields.io/badge/version-2.0.0-blue.svg) +![Python](https://img.shields.io/badge/python-3.7+-yellow.svg) ![License](https://img.shields.io/badge/license-MIT-green.svg) ![Category](https://img.shields.io/badge/category-OSINT-orange.svg) ![OPSEC](https://img.shields.io/badge/OPSEC-friendly-green.svg) -Una potente herramienta OSINT diseñada para la verificación, análisis de seguridad y reconocimiento de direcciones de correo electrónico. Ideal para investigadores de seguridad, analistas OSINT, profesionales de ciberseguridad y entusiastas del Bug Bounty. +Una potente herramienta OSINT diseñada para la verificación, análisis de seguridad y reconocimiento de direcciones de correo electrónico. Reescrita completamente en Python para mayor flexibilidad y mantenibilidad. Ideal para investigadores de seguridad, analistas OSINT, profesionales de ciberseguridad y entusiastas del Bug Bounty. ## 📋 Características Principales ### Verificación de Correos -- Análisis sintáctico avanzado -- Verificación de registros MX +- Análisis sintáctico avanzado con expresiones regulares +- Verificación asíncrona de registros MX - Validación SMTP en tiempo real - Detección de correos inexistentes -- Análisis de respuestas del servidor +- Análisis detallado de respuestas del servidor +- Soporte para conexiones seguras ### Análisis de Seguridad -- Puntuación de seguridad (0-100) -- Detección de SPF y política -- Análisis DMARC y nivel de aplicación -- Verificación de DKIM -- Detección de MTA-STS -- Análisis TLSRPT +- Sistema de puntuación de seguridad mejorado (0-100) +- Detección y análisis avanzado de SPF +- Análisis DMARC con evaluación de políticas +- Verificación multi-selector de DKIM +- Detección de MTA-STS y TLSRPT - Verificación DNSSEC -- Evaluación de spoofing posible +- Análisis detallado de posibilidades de spoofing +- Evaluación de configuraciones de seguridad -### Características OSINT -- Fingerprinting de servidores -- Análisis de infraestructura -- Detección de protecciones -- Modo sigiloso para OPSEC -- Análisis detallado en modo verbose +### Características OSINT & OPSEC +- Fingerprinting avanzado de servidores +- Análisis de infraestructura de correo +- Detección de protecciones y vulnerabilidades +- Modo sigiloso mejorado para OPSEC +- Sistema de logging detallado +- Soporte para proxies/VPN ## 🚀 Instalación ### Requisitos del Sistema +- Python 3.7+ +- pip (gestor de paquetes de Python) + +### Dependencias Python ```bash -# Arch Linux -sudo pacman -S bind-tools openbsd-netcat coreutils bc - -# Debian/Ubuntu -sudo apt install bind9-host netcat coreutils bc - -# Kali Linux -sudo apt update && sudo apt install bind9-host netcat-openbsd coreutils bc +pip install -r requirements.txt ``` +Las dependencias principales incluyen: +- dnspython +- rich +- asyncio + ### Instalación Rápida ```bash git clone https://condorcs.net/mrhacker/SEVO.git cd SEVO -chmod +x sevo -./sevo --version +pip install -r requirements.txt +python sevo.py --version ``` ## 💡 Uso ### Sintaxis Básica ```bash -./sevo [opciones] +python sevo.py [opciones] ``` ### Opciones Disponibles @@ -74,21 +79,21 @@ chmod +x sevo ### Ejemplos de Uso ```bash # Verificación básica -./sevo usuario@dominio.com +python sevo.py usuario@dominio.com # Análisis detallado con información de seguridad -./sevo -v usuario@dominio.com +python sevo.py -v usuario@dominio.com # Modo sigiloso con delay de 2 segundos -./sevo -s -d 2 usuario@dominio.com +python sevo.py -s -d 2 usuario@dominio.com ``` ## 📊 Interpretación de Resultados ### Puntuación de Seguridad -- **80-100**: Excelente protección -- **50-79**: Protección moderada -- **0-49**: Protección débil +- **80-100**: Protección excelente (SPF estricto, DMARC enforced, DKIM) +- **50-79**: Protección moderada (algunas medidas implementadas) +- **0-49**: Protección débil (configuraciones ausentes o permisivas) ### Indicadores de Estado | Símbolo | Significado | @@ -106,12 +111,11 @@ chmod +x sevo ║ 📊 Puntuación de Seguridad: 95/100 ║ ║ ✅ Características de Seguridad Detectadas: -║ - SPF -║ - SPF_STRICT -║ - DMARC -║ - DMARC_ENFORCED -║ - DKIM -║ - TLSRPT +║ - SPF (Strict) +║ - DMARC (Enforced) +║ - DKIM (Valid) +║ - TLSRPT (Enabled) +║ - DNSSEC (Active) ║ ║ ⚠️ Vulnerabilidades Detectadas: ║ - MTA-STS no configurado @@ -119,75 +123,52 @@ chmod +x sevo ║ 🎯 Estado de Protecciones: ║ - SPF Estricto: ✅ ║ - DMARC Enforced: ✅ -║ - Spoofing Posible: ✅ NO +║ - Spoofing Posible: ❌ NO ╚════════════════════════════════════════════════════════════════ ``` -## 🛡️ Características de Seguridad Analizadas +## 🛡️ Métodos de Validación -### SPF (Sender Policy Framework) -- Presencia de registro SPF -- Política (-all, ~all, ?all, +all) -- Nivel de restricción +### Validación de Correo +- Verificación de sintaxis RFC 5322 +- Resolución DNS asíncrona +- Validación SMTP con soporte TLS +- Análisis de respuestas del servidor +- Detección de políticas anti-spam -### DMARC (Domain-based Message Authentication) -- Presencia de registro DMARC -- Política (reject, quarantine, none) -- Porcentaje de aplicación -- Nivel de enforcement - -### DKIM (DomainKeys Identified Mail) -- Verificación de selectores comunes -- Detección de claves públicas -- Estado de implementación - -### Protecciones Adicionales -- MTA-STS para seguridad de transporte -- TLSRPT para reportes TLS -- DNSSEC para seguridad DNS - -## 🎯 Casos de Uso - -### Investigaciones de Seguridad -- Validación de correos sospechosos -- Análisis de configuraciones -- Detección de vulnerabilidades - -### Auditorías -- Evaluación de seguridad de correo -- Verificación de configuraciones -- Identificación de riesgos - -### Bug Bounty -- Reconocimiento de objetivos -- Verificación de correos -- Análisis de infraestructura +### Análisis de Seguridad +- Verificación exhaustiva de SPF +- Análisis de políticas DMARC +- Verificación multi-selector DKIM +- Evaluación de seguridad de transporte +- Análisis de vectores de spoofing ## ⚠️ Consideraciones OPSEC -- Utilizar con VPN/Proxy cuando sea necesario -- Activar modo sigiloso para reconocimiento discreto -- Usar delays apropiados para evitar detección -- Limitar frecuencia de consultas -- Documentar hallazgos de forma segura +- Utilizar siempre a través de VPN/Proxy +- Activar modo sigiloso para reconocimiento +- Implementar delays apropiados +- Respetar límites de consultas +- Mantener logs seguros ## 📝 Notas Legales -Esta herramienta está diseñada para uso ético y profesional en: +Esta herramienta está diseñada exclusivamente para uso ético y profesional en: - Pruebas autorizadas - Investigaciones legítimas - Auditorías de seguridad - Análisis de sistemas propios -El uso indebido puede estar sujeto a restricciones legales. +El uso indebido está prohibido y puede estar sujeto a consecuencias legales. ## 🤝 Contribución Las contribuciones son bienvenidas: -- Reporte de bugs -- Nuevas características -- Mejoras de documentación -- Optimizaciones de código +1. Fork del repositorio +2. Crear rama de características +3. Commit de cambios +4. Push a la rama +5. Crear Pull Request ## 📜 Licencia @@ -195,5 +176,4 @@ Este proyecto está bajo la Licencia MIT. --- -⚡ Desarrollado con ❤️ por Kevin Muñoz - +⚡ Desarrollado con ❤️ por Kevin Muñoz (@MrHacker) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8fb1957 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +dnspython==2.7.0 +markdown-it-py==3.0.0 +mdurl==0.1.2 +Pygments==2.18.0 +rich==13.9.4 diff --git a/sevo b/sevo deleted file mode 100755 index ecd2a8a..0000000 --- a/sevo +++ /dev/null @@ -1,459 +0,0 @@ -#!/bin/bash - -# Versión del script -VERSION="1.1.0" - -# Colores y símbolos -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -MAGENTA='\033[0;35m' -CYAN='\033[0;36m' -NC='\033[0m' -CHECK_MARK="✓" -CROSS_MARK="✗" -WARN_MARK="⚠️" -LOADING="⏳" -SEARCH="🔍" - -VERBOSE=false -STEALTH=false -DELAY=0 -SECURITY_SCORE=0 -IS_SPOOFABLE=false -SPF_STRICT=false -DMARC_ENFORCED=false - -show_banner() { - echo " - ███████╗███╗ ███╗ █████╗ ██╗██╗ ██████╗ ███████╗██╗███╗ ██╗████████╗ - ██╔════╝████╗ ████║██╔══██╗██║██║ ██╔═══██╗██╔════╝██║████╗ ██║╚══██╔══╝ - █████╗ ██╔████╔██║███████║██║██║ ██║ ██║███████╗██║██╔██╗ ██║ ██║ - ██╔══╝ ██║╚██╔╝██║██╔══██║██║██║ ██║ ██║╚════██║██║██║╚██╗██║ ██║ - ███████╗██║ ╚═╝ ██║██║ ██║██║███████╗╚██████╔╝███████║██║██║ ╚████║ ██║ - ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝ ╚═════╝ ╚══════╝╚═╝╚═╝ ╚═══╝ ╚═╝ - " - echo -e "${CYAN} Email OSINT Validator v$VERSION${NC}" - echo -e "${YELLOW} Uso ético - Solo para investigación autorizada${NC}" - echo -} - -show_help() { - echo "Uso: $0 [opciones] " - echo - echo "Opciones:" - echo " -v, --verbose Modo verbose, muestra información detallada" - echo " -s, --stealth Modo sigiloso, más lento pero menos detectable" - echo " -d, --delay N Añade un delay de N segundos entre consultas" - echo " -h, --help Muestra esta ayuda" - echo " --version Muestra la versión" - echo - echo "Ejemplos:" - echo " $0 usuario@dominio.com" - echo " $0 -v usuario@dominio.com" - echo " $0 -s -d 2 usuario@dominio.com" - exit 0 -} - -show_spinner() { - local pid=$1 - local delay=0.1 - local spinstr='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' - printf "\r" - while ps -p $pid > /dev/null 2>&1; do - local temp=${spinstr#?} - printf "\r[%c] " "$spinstr" - local spinstr=$temp${spinstr%"$temp"} - sleep $delay - done - printf "\r \r" -} - -log() { - local level=$1 - local message=$2 - if [[ $VERBOSE == true ]] || [[ $level != "DEBUG" ]]; then - case $level in - "INFO") echo -e "${GREEN}${CHECK_MARK}${NC} $message";; - "WARN") echo -e "${YELLOW}${WARN_MARK}${NC} $message";; - "ERROR") echo -e "${RED}${CROSS_MARK}${NC} $message";; - "DEBUG") echo -e "${BLUE}${SEARCH}${NC} $message";; - esac - fi -} -analyze_mx_security() { - local domain=$1 - local security_features=() - local vulnerabilities=() - local spf_strict=false - local dmarc_enforced=false - local spoofable=false - local security_score=0 - local max_score=100 - - log "DEBUG" "Iniciando análisis de seguridad profundo para $domain" - - log "DEBUG" "Analizando registros SPF..." - local spf_record=$(host -t TXT "$domain" | grep "v=spf1") - if [ -n "$spf_record" ]; then - security_features+=("SPF") - security_score=$((security_score + 20)) - - if [[ $spf_record =~ "-all" ]]; then - security_features+=("SPF_STRICT") - spf_strict=true - security_score=$((security_score + 15)) - elif [[ $spf_record =~ "~all" ]]; then - security_features+=("SPF_SOFT_FAIL") - vulnerabilities+=("SPF no es estricto (usa ~all)") - security_score=$((security_score + 10)) - elif [[ $spf_record =~ "\?all" ]]; then - vulnerabilities+=("SPF en modo neutral") - security_score=$((security_score + 5)) - elif [[ $spf_record =~ "\+all" ]]; then - vulnerabilities+=("SPF permite cualquier remitente") - spoofable=true - fi - else - vulnerabilities+=("No se encontró registro SPF") - spoofable=true - fi - - log "DEBUG" "Analizando política DMARC..." - local dmarc_record=$(host -t TXT "_dmarc.$domain" | grep "v=DMARC1") - if [ -n "$dmarc_record" ]; then - security_features+=("DMARC") - security_score=$((security_score + 20)) - - if [[ $dmarc_record =~ "p=reject" ]]; then - security_features+=("DMARC_ENFORCED") - dmarc_enforced=true - security_score=$((security_score + 15)) - elif [[ $dmarc_record =~ "p=quarantine" ]]; then - security_features+=("DMARC_QUARANTINE") - security_score=$((security_score + 10)) - elif [[ $dmarc_record =~ "p=none" ]]; then - vulnerabilities+=("DMARC en modo monitoreo") - security_score=$((security_score + 5)) - fi - - if [[ $dmarc_record =~ "pct=100" ]] || [[ ! $dmarc_record =~ "pct=" ]]; then - security_score=$((security_score + 5)) - else - local pct=$(echo "$dmarc_record" | grep -oP 'pct=\K[0-9]+') - vulnerabilities+=("DMARC solo aplicado al $pct% del tráfico") - fi - else - vulnerabilities+=("No se encontró registro DMARC") - spoofable=true - fi - - log "DEBUG" "Analizando configuración DKIM..." - local dkim_selectors=("default" "google" "mail" "email" "key1" "selector1" "selector2") - local dkim_found=false - - for selector in "${dkim_selectors[@]}"; do - if host -t TXT "${selector}._domainkey.$domain" 2>/dev/null | grep -q "v=DKIM1"; then - security_features+=("DKIM") - security_score=$((security_score + 15)) - dkim_found=true - break - fi - done - - if ! $dkim_found; then - vulnerabilities+=("No se encontró registro DKIM") - fi - - log "DEBUG" "Verificando MTA-STS..." - if host -t TXT "_mta-sts.$domain" 2>/dev/null | grep -q "v=STSv1"; then - security_features+=("MTA-STS") - security_score=$((security_score + 10)) - else - vulnerabilities+=("MTA-STS no configurado") - fi - - if host -t TXT "_smtp._tls.$domain" 2>/dev/null | grep -q "v=TLSRPTv1"; then - security_features+=("TLSRPT") - security_score=$((security_score + 5)) - fi - - if dig "$domain" +dnssec | grep -q "RRSIG"; then - security_features+=("DNSSEC") - security_score=$((security_score + 10)) - fi - - cat << EOF -╔════════════════════════════════════════════════════════════════ -║ 🔒 Análisis de Seguridad para $domain -╠════════════════════════════════════════════════════════════════ -║ 📊 Puntuación de Seguridad: $security_score/$max_score -EOF - - if [ ${#security_features[@]} -gt 0 ]; then - cat << EOF -║ -║ ✅ Características de Seguridad Detectadas: -EOF - for feature in "${security_features[@]}"; do - printf "║ - %s\n" "$feature" - done - fi - - if [ ${#vulnerabilities[@]} -gt 0 ]; then - cat << EOF -║ -║ ⚠️ Vulnerabilidades Detectadas: -EOF - for vuln in "${vulnerabilities[@]}"; do - printf "║ - %s\n" "$vuln" - done - fi - - cat << EOF -║ -║ 🎯 Estado de Protecciones: -║ - SPF Estricto: $(if $spf_strict; then echo "✅"; else echo "❌"; fi) -║ - DMARC Enforced: $(if $dmarc_enforced; then echo "✅"; else echo "❌"; fi) -║ - Spoofing Posible: $(if $spoofable; then echo "⚠️ SÍ"; else echo "✅ NO"; fi) -╚════════════════════════════════════════════════════════════════ -EOF - - SECURITY_SCORE=$security_score - IS_SPOOFABLE=$spoofable - SPF_STRICT=$spf_strict - DMARC_ENFORCED=$dmarc_enforced -} - - fingerprint_server() { - local response=$1 - local server_info=$(echo "$response" | grep -i "^220" | head -n1) - local additional_info=$(echo "$response" | grep -i "at your service" | head -n1) - - if [[ $server_info =~ "mx.google.com" ]] || [[ $server_info =~ "gmail-smtp" ]] || [[ $additional_info =~ "mx.google.com" ]]; then - if [[ $server_info =~ "gsmtp" ]]; then - if [[ $HOSTNAME =~ "gmail-smtp" ]]; then - log "INFO" "Servidor detectado: Google Gmail (SMTP)" - elif [[ $HOSTNAME =~ "aspmx" ]]; then - log "INFO" "Servidor detectado: Google Workspace" - elif [[ $HOSTNAME =~ "google" ]]; then - log "INFO" "Servidor detectado: Google Mail Services" - else - log "INFO" "Servidor detectado: Google Mail Infrastructure" - fi - [[ $VERBOSE == true ]] && log "DEBUG" "Motor SMTP: Google SMTP (gsmtp)" - fi - - if [[ $response =~ "STARTTLS" ]]; then - [[ $VERBOSE == true ]] && log "DEBUG" "Soporta: STARTTLS (Cifrado TLS)" - fi - if [[ $response =~ "SMTPUTF8" ]]; then - [[ $VERBOSE == true ]] && log "DEBUG" "Soporta: SMTPUTF8 (Caracteres internacionales)" - fi - if [[ $response =~ "SIZE" ]]; then - local size=$(echo "$response" | grep -i "SIZE" | grep -oP '\d+') - [[ $VERBOSE == true ]] && log "DEBUG" "Tamaño máximo de mensaje: $(($size/1024/1024))MB" - fi - - return 0 - elif [[ $server_info =~ "Microsoft" ]]; then - log "INFO" "Servidor detectado: Microsoft Exchange/Office 365" - [[ $VERBOSE == true ]] && log "DEBUG" "Sistema de correo empresarial Microsoft Exchange" - elif [[ $server_info =~ "Postfix" ]]; then - log "INFO" "Servidor detectado: Postfix" - [[ $VERBOSE == true ]] && log "DEBUG" "Servidor de correo Postfix (Linux)" - elif [[ $server_info =~ "Exim" ]]; then - log "INFO" "Servidor detectado: Exim" - [[ $VERBOSE == true ]] && log "DEBUG" "Servidor de correo Exim" - elif [[ $server_info =~ "Sendmail" ]]; then - log "INFO" "Servidor detectado: Sendmail" - [[ $VERBOSE == true ]] && log "DEBUG" "Servidor de correo Sendmail" - elif [[ $server_info =~ "Zimbra" ]]; then - log "INFO" "Servidor detectado: Zimbra" - [[ $VERBOSE == true ]] && log "DEBUG" "Suite de colaboración Zimbra" - else - log "INFO" "Servidor no identificado específicamente" - [[ $VERBOSE == true ]] && log "DEBUG" "Banner del servidor: $server_info" - fi -} - - validate_email() { - local email=$1 - local domain=$(echo "$email" | cut -d "@" -f 2) - local our_hostname="email-validator-osint.local" - - log "INFO" "Verificando correo: $email" - - if ! echo "$email" | grep -E "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$" >/dev/null; then - log "ERROR" "Formato de correo inválido" - return 1 - fi - log "INFO" "La sintaxis del correo es correcta" - - log "INFO" "Buscando registros MX..." - local mx_output=$(host -t MX "$domain") - if [ $? -ne 0 ]; then - log "ERROR" "No se encontraron registros MX para $domain" - return 1 - fi - - log "INFO" "Registros MX encontrados:" - local primary_mx="" - local current_priority=999 - - while read -r line; do - if [[ $line =~ "is handled by" ]]; then - local server=$(echo "$line" | awk '{print $NF}' | sed 's/\.$//') - local priority=$(echo "$line" | awk '{print $(NF-1)}') - log "INFO" "MX record encontrado: $server (Prioridad $priority)" - - if [ -z "$primary_mx" ] || [ "$priority" -lt "$current_priority" ]; then - primary_mx=$server - current_priority=$priority - fi - fi - done <<< "$mx_output" - - [[ $VERBOSE == true ]] && analyze_mx_security "$domain" - - if [ -n "$primary_mx" ]; then - [[ $STEALTH == true ]] && sleep $DELAY - - echo -ne "${LOADING} Iniciando diálogo con $primary_mx " - - temp_commands=$(mktemp) - { - echo "EHLO $our_hostname" - echo "MAIL FROM:" - echo "RCPT TO:<$email>" - echo "QUIT" - } > "$temp_commands" - - nc -w 10 "$primary_mx" 25 < "$temp_commands" > response.tmp 2>&1 & - - nc_pid=$! - show_spinner $nc_pid - wait $nc_pid - - rm -f "$temp_commands" - - echo -e "\r${CHECK_MARK} Diálogo con $primary_mx completado " - log "INFO" "Respuestas del servidor:" - - local email_status="válido" - local problem_description="" - local valid_response=false - - while read -r line; do - if [[ $line =~ ^[0-9]{3} ]]; then - echo " $line" - local code=${line:0:3} - valid_response=true - - if [[ $code == "220" ]] && [[ $VERBOSE == true ]]; then - fingerprint_server "$line" - fi - - case $code in - 250) - if [[ $line =~ "RCPT" ]]; then - email_status="válido" - log "INFO" "Correo verificado exitosamente" - fi - ;; - 421) - email_status="no verificable" - problem_description="El servidor no está disponible temporalmente" - log "WARN" "$problem_description" - ;; - 450|452) - email_status="temporalmente no disponible" - problem_description="Buzón temporalmente no disponible" - log "WARN" "$problem_description" - ;; - 500|501|502|503|504) - if [[ $VERBOSE == true ]]; then - log "DEBUG" "Código $code: Error de protocolo (normal durante la negociación)" - fi - ;; - 550) - if [[ $line =~ "RCPT" ]] || [[ $line =~ "user" ]] || [[ $line =~ "recipient" ]]; then - email_status="no válido" - problem_description="La dirección de correo no existe" - log "ERROR" "$problem_description" - fi - ;; - 551|553) - email_status="no válido" - problem_description="La dirección de correo no está permitida" - log "ERROR" "$problem_description" - ;; - 554) - email_status="no válido" - problem_description="Transacción fallida" - log "ERROR" "$problem_description" - ;; - esac - fi - done < response.tmp - - rm -f response.tmp - - if [[ "$email_status" == "válido" ]]; then - log "INFO" "El correo $email es válido" - return 0 - elif [[ "$email_status" == "no válido" ]]; then - log "ERROR" "El correo $email no es válido" - [ -n "$problem_description" ] && log "ERROR" "Razón: $problem_description" - return 1 - else - log "WARN" "Estado del correo $email: $email_status" - [ -n "$problem_description" ] && log "WARN" "Razón: $problem_description" - return 1 - fi - fi - } - -for cmd in host nc timeout dig bc mktemp; do - if ! command -v $cmd &> /dev/null; then - echo -e "${RED}${CROSS_MARK} Error: El comando '$cmd' no está instalado.${NC}" - echo " Instala las dependencias necesarias con:" - echo " sudo pacman -S bind-tools openbsd-netcat coreutils bc" - echo " o" - echo " sudo apt install bind9-host netcat coreutils bc" - exit 1 - fi -done - -while [[ $# -gt 0 ]]; do - case $1 in - -v|--verbose) VERBOSE=true; shift;; - -s|--stealth) STEALTH=true; shift;; - -d|--delay) DELAY="$2"; shift 2;; - -h|--help) show_help;; - --version) echo "Email Validator OSINT v$VERSION"; exit 0;; - *) EMAIL="$1"; shift;; - esac -done - -if [ -z "$EMAIL" ]; then - show_help -fi - -show_banner -validate_email "$EMAIL" -exit_code=$? - -if [[ $VERBOSE == true ]] && [[ $exit_code -eq 0 ]]; then - echo -e "\n${GREEN}🎉 Análisis completado exitosamente${NC}" - if [[ $SECURITY_SCORE -ge 80 ]]; then - echo -e "${GREEN}🛡️ El dominio tiene buenas protecciones de seguridad${NC}" - elif [[ $SECURITY_SCORE -ge 50 ]]; then - echo -e "${YELLOW}⚠️ El dominio tiene protecciones moderadas${NC}" - else - echo -e "${RED}⚠️ El dominio tiene protecciones débiles${NC}" - fi -fi - -exit $exit_code diff --git a/sevo.py b/sevo.py new file mode 100644 index 0000000..e042c70 --- /dev/null +++ b/sevo.py @@ -0,0 +1,299 @@ +#!/usr/bin/env python + +import asyncio +import dns.resolver +import argparse +import re +import socket +import sys +import time +from dataclasses import dataclass +from typing import List, Optional, Tuple +from rich.console import Console +from rich.table import Table +from rich import print as rprint + +VERSION = "2.0.0" + +@dataclass +class SecurityAnalysis: + score: int + features: List[str] + vulnerabilities: List[str] + spf_strict: bool + dmarc_enforced: bool + spoofable: bool + +class Colors: + GREEN = "\033[0;32m" + RED = "\033[0;31m" + YELLOW = "\033[1;33m" + BLUE = "\033[0;34m" + CYAN = "\033[0;36m" + NC = "\033[0m" + +class EmailValidator: + def __init__(self, verbose: bool = False, stealth: bool = False, delay: int = 0): + self.verbose = verbose + self.stealth = stealth + self.delay = delay + self.console = Console() + + @staticmethod + def show_banner(): + banner = """ + ███████╗███╗ ███╗ █████╗ ██╗██╗ ██████╗ ███████╗██╗███╗ ██╗████████╗ + ██╔════╝████╗ ████║██╔══██╗██║██║ ██╔═══██╗██╔════╝██║████╗ ██║╚══██╔══╝ + █████╗ ██╔████╔██║███████║██║██║ ██║ ██║███████╗██║██╔██╗ ██║ ██║ + ██╔══╝ ██║╚██╔╝██║██╔══██║██║██║ ██║ ██║╚════██║██║██║╚██╗██║ ██║ + ███████╗██║ ╚═╝ ██║██║ ██║██║███████╗╚██████╔╝███████║██║██║ ╚████║ ██║ + ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝ ╚═════╝ ╚══════╝╚═╝╚═╝ ╚═══╝ ╚═╝ + """ + print(f"{Colors.CYAN}{banner}{Colors.NC}") + print(f"{Colors.CYAN} Email OSINT Validator v{VERSION}{Colors.NC}") + print(f"{Colors.BLUE} Desarrollado por: Kevin Muñoz (MrHacker|TheSL18){Colors.NC}") + print(f"{Colors.YELLOW} Uso ético - Solo para investigación autorizada{Colors.NC}\n") + + async def analyze_mx_security(self, domain: str) -> SecurityAnalysis: + security_features = [] + vulnerabilities = [] + security_score = 0 + spf_strict = False + dmarc_enforced = False + spoofable = False + + try: + # Check SPF + try: + answers = dns.resolver.resolve(domain, 'TXT') + spf_record = next((str(record) for record in answers + if str(record).startswith('"v=spf1')), None) + + if spf_record: + security_features.append("SPF") + security_score += 20 + + if '-all' in spf_record: + security_features.append("SPF_STRICT") + spf_strict = True + security_score += 15 + elif '~all' in spf_record: + security_features.append("SPF_SOFT_FAIL") + vulnerabilities.append("SPF no es estricto (usa ~all)") + security_score += 10 + elif '?all' in spf_record: + vulnerabilities.append("SPF en modo neutral") + security_score += 5 + elif '+all' in spf_record: + vulnerabilities.append("SPF permite cualquier remitente") + spoofable = True + else: + vulnerabilities.append("No se encontró registro SPF") + spoofable = True + except Exception as e: + vulnerabilities.append(f"Error al verificar SPF: {str(e)}") + + # Check DMARC + try: + answers = dns.resolver.resolve(f'_dmarc.{domain}', 'TXT') + dmarc_record = next((str(record) for record in answers + if str(record).startswith('"v=DMARC1')), None) + + if dmarc_record: + security_features.append("DMARC") + security_score += 20 + + if 'p=reject' in dmarc_record: + security_features.append("DMARC_ENFORCED") + dmarc_enforced = True + security_score += 15 + elif 'p=quarantine' in dmarc_record: + security_features.append("DMARC_QUARANTINE") + security_score += 10 + elif 'p=none' in dmarc_record: + vulnerabilities.append("DMARC en modo monitoreo") + security_score += 5 + else: + vulnerabilities.append("No se encontró registro DMARC") + spoofable = True + except Exception as e: + vulnerabilities.append(f"Error al verificar DMARC: {str(e)}") + + # Check DKIM + dkim_selectors = ['default', 'google', 'mail', 'email', 'key1', 'selector1', 'selector2'] + dkim_found = False + + for selector in dkim_selectors: + try: + dns.resolver.resolve(f'{selector}._domainkey.{domain}', 'TXT') + security_features.append("DKIM") + security_score += 15 + dkim_found = True + break + except: + continue + + if not dkim_found: + vulnerabilities.append("No se encontró registro DKIM") + + except Exception as e: + vulnerabilities.append(f"Error en análisis de seguridad: {str(e)}") + + return SecurityAnalysis( + score=security_score, + features=security_features, + vulnerabilities=vulnerabilities, + spf_strict=spf_strict, + dmarc_enforced=dmarc_enforced, + spoofable=spoofable + ) + + def fingerprint_server(self, response: str) -> Optional[str]: + server_info = re.search(r'^220.*$', response, re.MULTILINE | re.IGNORECASE) + if not server_info: + return None + + server_info = server_info.group(0) + + if 'mx.google.com' in server_info.lower() or 'gmail-smtp' in server_info.lower(): + return "Google Mail Infrastructure" + elif 'microsoft' in server_info.lower(): + return "Microsoft Exchange/Office 365" + elif 'postfix' in server_info.lower(): + return "Postfix" + elif 'exim' in server_info.lower(): + return "Exim" + elif 'sendmail' in server_info.lower(): + return "Sendmail" + elif 'zimbra' in server_info.lower(): + return "Zimbra" + + return "Unknown Server" + + async def validate_email(self, email: str) -> bool: + if not re.match(r'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$', email): + rprint("[red]❌ Formato de correo inválido[/]") + return False + + rprint("[green]✓ La sintaxis del correo es correcta[/]") + + domain = email.split('@')[1] + + try: + rprint("[cyan]🔍 Buscando registros MX...[/]") + mx_records = sorted( + [(rdata.preference, rdata.exchange.to_text().rstrip('.')) + for rdata in dns.resolver.resolve(domain, 'MX')], + key=lambda x: x[0] + ) + + if not mx_records: + rprint(f"[red]❌ No se encontraron registros MX para {domain}[/]") + return False + + for preference, server in mx_records: + rprint(f"[green]✓ MX record encontrado: {server} (Prioridad {preference})[/]") + + if self.verbose: + security_analysis = await self.analyze_mx_security(domain) + self.display_security_analysis(domain, security_analysis) + + primary_mx = mx_records[0][1] + + if self.stealth: + time.sleep(self.delay) + + rprint(f"[cyan]⏳ Iniciando diálogo con {primary_mx}[/]") + + try: + with socket.create_connection((primary_mx, 25), timeout=10) as sock: + sock.settimeout(10) + + response = sock.recv(1024).decode() + if self.verbose: + server_type = self.fingerprint_server(response) + if server_type: + rprint(f"[blue]ℹ Servidor detectado: {server_type}[/]") + + commands = [ + f"HELO email-validator-osint.local\r\n", + f"MAIL FROM:\r\n", + f"RCPT TO:<{email}>\r\n", + "QUIT\r\n" + ] + + for cmd in commands: + sock.send(cmd.encode()) + response = sock.recv(1024).decode() + + if self.verbose: + rprint(f"[cyan]→ {cmd.strip()}[/]") + rprint(f"[cyan]← {response.strip()}[/]") + + code = response[:3] + if code == "550": + rprint(f"[red]❌ El correo {email} no es válido[/]") + return False + elif code not in ["220", "250", "221"]: + rprint(f"[yellow]⚠ Respuesta inesperada del servidor: {response.strip()}[/]") + return False + + rprint(f"[green]✓ El correo {email} es válido[/]") + return True + + except Exception as e: + rprint(f"[red]❌ Error al conectar con el servidor: {str(e)}[/]") + return False + + except Exception as e: + rprint(f"[red]❌ Error: {str(e)}[/]") + return False + + def display_security_analysis(self, domain: str, analysis: SecurityAnalysis): + table = Table(title=f"🔒 Análisis de Seguridad para {domain}") + + table.add_column("Categoría", style="cyan") + table.add_column("Detalle", style="white") + + table.add_row( + "📊 Puntuación de Seguridad", + f"{analysis.score}/100" + ) + + if analysis.features: + table.add_row( + "✅ Características de Seguridad", + "\n".join(analysis.features) + ) + + if analysis.vulnerabilities: + table.add_row( + "⚠️ Vulnerabilidades", + "\n".join(analysis.vulnerabilities) + ) + + table.add_row( + "🎯 Estado de Protecciones", + f"SPF Estricto: {'✅' if analysis.spf_strict else '❌'}\n" + f"DMARC Enforced: {'✅' if analysis.dmarc_enforced else '❌'}\n" + f"Spoofing Posible: {'⚠️ SÍ' if analysis.spoofable else '✅ NO'}" + ) + + self.console.print(table) + +async def main(): + parser = argparse.ArgumentParser(description='Email OSINT Validator') + parser.add_argument('email', help='Email to validate') + parser.add_argument('-v', '--verbose', action='store_true', help='Verbose mode') + parser.add_argument('-s', '--stealth', action='store_true', help='Stealth mode') + parser.add_argument('-d', '--delay', type=int, default=0, help='Delay between queries') + args = parser.parse_args() + + validator = EmailValidator(verbose=args.verbose, stealth=args.stealth, delay=args.delay) + validator.show_banner() + + result = await validator.validate_email(args.email) + sys.exit(0 if result else 1) + +if __name__ == "__main__": + asyncio.run(main())