Compare commits

..

3 Commits

4 changed files with 378 additions and 529 deletions

168
README.md
View File

@ -1,65 +1,70 @@
# 🕵️‍♂️ SEVO - Security Email Validator OSINT v1.0.0
# 🕵️‍♂️ SEVO - Security Email Validator OSINT v2.0.0
![Version](https://img.shields.io/badge/version-1.0.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
cd SEVO
pip install -r requirements.txt
python sevo.py --version
```
## 💡 Uso
### Sintaxis Básica
```bash
./sevo [opciones] <email>
python sevo.py [opciones] <email>
```
### 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 <Mr.Hacker>
⚡ Desarrollado con ❤️ por Kevin Muñoz (@MrHacker)

5
requirements.txt Normal file
View File

@ -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

435
sevo
View File

@ -1,435 +0,0 @@
#!/bin/bash
# Versión del script
VERSION="1.0.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] <email>"
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)
if [[ $server_info =~ "Microsoft" ]]; then
log "INFO" "Servidor detectado: Microsoft Exchange/Office 365"
[[ $VERBOSE == true ]] && log "DEBUG" "Sistema de correo empresarial Microsoft"
elif [[ $server_info =~ "Google" ]]; then
log "INFO" "Servidor detectado: Google Workspace"
[[ $VERBOSE == true ]] && log "DEBUG" "Sistema de correo Google Workspace"
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:<validator@$our_hostname>"
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

299
sevo.py Normal file
View File

@ -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:<validator@email-validator-osint.local>\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())