feat(security): mejora detección de spoofing y análisis DMARC
- Agrega evaluación de fortaleza SPF/DMARC (0-3) - Implementa verificación PCT en DMARC - Añade análisis de registros PTR - Actualiza documentación y ejemplos - Incrementa versión a 2.1.0
This commit is contained in:
parent
fbc588a4b6
commit
14d9d5d93e
50
README.md
50
README.md
@ -1,6 +1,6 @@
|
|||||||
# 🕵️♂️ SEVO - Security Email Validator OSINT v2.0.0
|
# 🕵️♂️ SEVO - Security Email Validator OSINT v2.1.0
|
||||||
|
|
||||||
![Version](https://img.shields.io/badge/version-2.0.0-blue.svg)
|
![Version](https://img.shields.io/badge/version-2.1.0-blue.svg)
|
||||||
![Python](https://img.shields.io/badge/python-3.7+-yellow.svg)
|
![Python](https://img.shields.io/badge/python-3.7+-yellow.svg)
|
||||||
![License](https://img.shields.io/badge/license-MIT-green.svg)
|
![License](https://img.shields.io/badge/license-MIT-green.svg)
|
||||||
![Category](https://img.shields.io/badge/category-OSINT-orange.svg)
|
![Category](https://img.shields.io/badge/category-OSINT-orange.svg)
|
||||||
@ -18,15 +18,20 @@ Una potente herramienta OSINT diseñada para la verificación, análisis de segu
|
|||||||
- Análisis detallado de respuestas del servidor
|
- Análisis detallado de respuestas del servidor
|
||||||
- Soporte para conexiones seguras
|
- Soporte para conexiones seguras
|
||||||
|
|
||||||
### Análisis de Seguridad
|
### Análisis de Seguridad Mejorado
|
||||||
- Sistema de puntuación de seguridad mejorado (0-100)
|
- Sistema de puntuación de seguridad avanzado (0-100)
|
||||||
- Detección y análisis avanzado de SPF
|
- Detección y análisis exhaustivo de SPF
|
||||||
- Análisis DMARC con evaluación de políticas
|
- Evaluación de mecanismos SPF
|
||||||
|
- Detección de configuraciones débiles
|
||||||
|
- Análisis de modificadores
|
||||||
|
- Análisis DMARC completo
|
||||||
|
- Verificación de porcentaje de aplicación
|
||||||
|
- Evaluación de políticas y modos
|
||||||
|
- Análisis de reportes y alineación
|
||||||
- Verificación multi-selector de DKIM
|
- Verificación multi-selector de DKIM
|
||||||
- Detección de MTA-STS y TLSRPT
|
- Análisis PTR
|
||||||
- Verificación DNSSEC
|
- Detección mejorada de susceptibilidad a spoofing
|
||||||
- Análisis detallado de posibilidades de spoofing
|
- Evaluación de fortaleza de configuración (SPF/DMARC)
|
||||||
- Evaluación de configuraciones de seguridad
|
|
||||||
|
|
||||||
### Características OSINT & OPSEC
|
### Características OSINT & OPSEC
|
||||||
- Fingerprinting avanzado de servidores
|
- Fingerprinting avanzado de servidores
|
||||||
@ -91,10 +96,28 @@ python sevo.py -s -d 2 usuario@dominio.com
|
|||||||
## 📊 Interpretación de Resultados
|
## 📊 Interpretación de Resultados
|
||||||
|
|
||||||
### Puntuación de Seguridad
|
### Puntuación de Seguridad
|
||||||
- **80-100**: Protección excelente (SPF estricto, DMARC enforced, DKIM)
|
- **80-100**: Protección excelente (SPF estricto, DMARC enforced 100%, DKIM)
|
||||||
- **50-79**: Protección moderada (algunas medidas implementadas)
|
- **50-79**: Protección moderada (algunas medidas implementadas)
|
||||||
- **0-49**: Protección débil (configuraciones ausentes o permisivas)
|
- **0-49**: Protección débil (configuraciones ausentes o permisivas)
|
||||||
|
|
||||||
|
### Detección de Spoofing
|
||||||
|
La herramienta analiza:
|
||||||
|
- Fortaleza de SPF (escala 0-3)
|
||||||
|
- 3: Configuración estricta (-all)
|
||||||
|
- 2: Configuración moderada (~all)
|
||||||
|
- 1: Configuración débil (?all)
|
||||||
|
- 0: Sin protección (+all)
|
||||||
|
- Fortaleza de DMARC (escala 0-3)
|
||||||
|
- 3: Reject enforced
|
||||||
|
- 2: Quarantine
|
||||||
|
- 1: Modo monitoreo
|
||||||
|
- 0: Sin DMARC
|
||||||
|
- Porcentaje de aplicación DMARC
|
||||||
|
- Configuración de reportes (RUA/RUF)
|
||||||
|
- Modos de alineación DKIM/SPF
|
||||||
|
- Validez de registros PTR
|
||||||
|
- Acumulación de vulnerabilidades
|
||||||
|
|
||||||
### Indicadores de Estado
|
### Indicadores de Estado
|
||||||
| Símbolo | Significado |
|
| Símbolo | Significado |
|
||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
@ -118,12 +141,13 @@ python sevo.py -s -d 2 usuario@dominio.com
|
|||||||
║ - DNSSEC (Active)
|
║ - DNSSEC (Active)
|
||||||
║
|
║
|
||||||
║ ⚠️ Vulnerabilidades Detectadas:
|
║ ⚠️ Vulnerabilidades Detectadas:
|
||||||
║ - MTA-STS no configurado
|
║ - DMARC no aplicado al 100%
|
||||||
|
║ - Falta registro PTR válido
|
||||||
║
|
║
|
||||||
║ 🎯 Estado de Protecciones:
|
║ 🎯 Estado de Protecciones:
|
||||||
║ - SPF Estricto: ✅
|
║ - SPF Estricto: ✅
|
||||||
║ - DMARC Enforced: ✅
|
║ - DMARC Enforced: ✅
|
||||||
║ - Spoofing Posible: ❌ NO
|
║ - Spoofing Posible: ⚠️ SÍ
|
||||||
╚════════════════════════════════════════════════════════════════
|
╚════════════════════════════════════════════════════════════════
|
||||||
```
|
```
|
||||||
|
|
||||||
|
94
sevo.py
94
sevo.py
@ -13,7 +13,7 @@ from rich.console import Console
|
|||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich import print as rprint
|
from rich import print as rprint
|
||||||
|
|
||||||
VERSION = "2.0.0"
|
VERSION = "2.1.0"
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class SecurityAnalysis:
|
class SecurityAnalysis:
|
||||||
@ -61,9 +61,11 @@ class EmailValidator:
|
|||||||
spf_strict = False
|
spf_strict = False
|
||||||
dmarc_enforced = False
|
dmarc_enforced = False
|
||||||
spoofable = False
|
spoofable = False
|
||||||
|
spf_strength = 0
|
||||||
|
dmarc_strength = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Check SPF
|
# Verificar SPF
|
||||||
try:
|
try:
|
||||||
answers = dns.resolver.resolve(domain, 'TXT')
|
answers = dns.resolver.resolve(domain, 'TXT')
|
||||||
spf_record = next((str(record) for record in answers
|
spf_record = next((str(record) for record in answers
|
||||||
@ -73,19 +75,34 @@ class EmailValidator:
|
|||||||
security_features.append("SPF")
|
security_features.append("SPF")
|
||||||
security_score += 20
|
security_score += 20
|
||||||
|
|
||||||
|
# Analizar mecanismos SPF
|
||||||
|
mechanisms = re.findall(r'[\+\-\~\?]?(ip4|ip6|a|mx|ptr|exists|include|all)[:\/]?[^\s]*', spf_record)
|
||||||
|
|
||||||
if '-all' in spf_record:
|
if '-all' in spf_record:
|
||||||
security_features.append("SPF_STRICT")
|
security_features.append("SPF_STRICT")
|
||||||
spf_strict = True
|
spf_strict = True
|
||||||
|
spf_strength = 3
|
||||||
security_score += 15
|
security_score += 15
|
||||||
elif '~all' in spf_record:
|
elif '~all' in spf_record:
|
||||||
security_features.append("SPF_SOFT_FAIL")
|
security_features.append("SPF_SOFT_FAIL")
|
||||||
vulnerabilities.append("SPF no es estricto (usa ~all)")
|
vulnerabilities.append("SPF no es estricto (usa ~all)")
|
||||||
|
spf_strength = 2
|
||||||
security_score += 10
|
security_score += 10
|
||||||
elif '?all' in spf_record:
|
elif '?all' in spf_record:
|
||||||
vulnerabilities.append("SPF en modo neutral")
|
vulnerabilities.append("SPF en modo neutral")
|
||||||
|
spf_strength = 1
|
||||||
security_score += 5
|
security_score += 5
|
||||||
elif '+all' in spf_record:
|
elif '+all' in spf_record:
|
||||||
vulnerabilities.append("SPF permite cualquier remitente")
|
vulnerabilities.append("SPF permite cualquier remitente")
|
||||||
|
spf_strength = 0
|
||||||
|
spoofable = True
|
||||||
|
|
||||||
|
if len(mechanisms) < 2:
|
||||||
|
vulnerabilities.append("SPF: Pocas reglas definidas")
|
||||||
|
if 'ptr' in spf_record:
|
||||||
|
vulnerabilities.append("SPF: Uso de mecanismo PTR (no recomendado)")
|
||||||
|
if any(m.startswith('+') for m in mechanisms):
|
||||||
|
vulnerabilities.append("SPF: Uso de modificador '+' explícito (riesgo de spoofing)")
|
||||||
spoofable = True
|
spoofable = True
|
||||||
else:
|
else:
|
||||||
vulnerabilities.append("No se encontró registro SPF")
|
vulnerabilities.append("No se encontró registro SPF")
|
||||||
@ -93,7 +110,7 @@ class EmailValidator:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
vulnerabilities.append(f"Error al verificar SPF: {str(e)}")
|
vulnerabilities.append(f"Error al verificar SPF: {str(e)}")
|
||||||
|
|
||||||
# Check DMARC
|
# Verificar DMARC
|
||||||
try:
|
try:
|
||||||
answers = dns.resolver.resolve(f'_dmarc.{domain}', 'TXT')
|
answers = dns.resolver.resolve(f'_dmarc.{domain}', 'TXT')
|
||||||
dmarc_record = next((str(record) for record in answers
|
dmarc_record = next((str(record) for record in answers
|
||||||
@ -103,23 +120,43 @@ class EmailValidator:
|
|||||||
security_features.append("DMARC")
|
security_features.append("DMARC")
|
||||||
security_score += 20
|
security_score += 20
|
||||||
|
|
||||||
if 'p=reject' in dmarc_record:
|
# Analizar política DMARC y opciones
|
||||||
security_features.append("DMARC_ENFORCED")
|
dmarc_policy = re.search(r'p=(reject|quarantine|none)', dmarc_record)
|
||||||
dmarc_enforced = True
|
pct_match = re.search(r'pct=(\d+)', dmarc_record)
|
||||||
security_score += 15
|
rua_match = re.search(r'rua=([^\s;]+)', dmarc_record)
|
||||||
elif 'p=quarantine' in dmarc_record:
|
ruf_match = re.search(r'ruf=([^\s;]+)', dmarc_record)
|
||||||
security_features.append("DMARC_QUARANTINE")
|
|
||||||
security_score += 10
|
if dmarc_policy:
|
||||||
elif 'p=none' in dmarc_record:
|
if dmarc_policy.group(1) == 'reject':
|
||||||
vulnerabilities.append("DMARC en modo monitoreo")
|
security_features.append("DMARC_ENFORCED")
|
||||||
security_score += 5
|
dmarc_enforced = True
|
||||||
|
dmarc_strength = 3
|
||||||
|
security_score += 15
|
||||||
|
elif dmarc_policy.group(1) == 'quarantine':
|
||||||
|
security_features.append("DMARC_QUARANTINE")
|
||||||
|
dmarc_strength = 2
|
||||||
|
security_score += 10
|
||||||
|
else: # none
|
||||||
|
vulnerabilities.append("DMARC en modo monitoreo")
|
||||||
|
dmarc_strength = 1
|
||||||
|
security_score += 5
|
||||||
|
|
||||||
|
if not pct_match or int(pct_match.group(1)) < 100:
|
||||||
|
vulnerabilities.append("DMARC: No aplicado al 100% de los mensajes")
|
||||||
|
spoofable = True
|
||||||
|
|
||||||
|
if not rua_match and not ruf_match:
|
||||||
|
vulnerabilities.append("DMARC: Sin configuración de reportes")
|
||||||
|
|
||||||
|
if not re.search(r'(adkim|aspf)=s', dmarc_record):
|
||||||
|
vulnerabilities.append("DMARC: Modo de alineación relajado")
|
||||||
else:
|
else:
|
||||||
vulnerabilities.append("No se encontró registro DMARC")
|
vulnerabilities.append("No se encontró registro DMARC")
|
||||||
spoofable = True
|
spoofable = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
vulnerabilities.append(f"Error al verificar DMARC: {str(e)}")
|
vulnerabilities.append(f"Error al verificar DMARC: {str(e)}")
|
||||||
|
|
||||||
# Check DKIM
|
# Verificar DKIM
|
||||||
dkim_selectors = ['default', 'google', 'mail', 'email', 'key1', 'selector1', 'selector2']
|
dkim_selectors = ['default', 'google', 'mail', 'email', 'key1', 'selector1', 'selector2']
|
||||||
dkim_found = False
|
dkim_found = False
|
||||||
|
|
||||||
@ -136,11 +173,28 @@ class EmailValidator:
|
|||||||
if not dkim_found:
|
if not dkim_found:
|
||||||
vulnerabilities.append("No se encontró registro DKIM")
|
vulnerabilities.append("No se encontró registro DKIM")
|
||||||
|
|
||||||
|
# Evaluación final de riesgo de spoofing
|
||||||
|
if spf_strength < 2 or dmarc_strength < 2:
|
||||||
|
spoofable = True
|
||||||
|
|
||||||
|
if len(vulnerabilities) > 3:
|
||||||
|
spoofable = True
|
||||||
|
|
||||||
|
# Verificaciones adicionales para misconfiguraciones comunes
|
||||||
|
try:
|
||||||
|
answers = dns.resolver.resolve(domain, 'A')
|
||||||
|
ip = str(answers[0])
|
||||||
|
ptr = dns.resolver.resolve_address(ip)
|
||||||
|
if not any(domain in str(r) for r in ptr):
|
||||||
|
vulnerabilities.append("Falta de registro PTR válido")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
vulnerabilities.append(f"Error en análisis de seguridad: {str(e)}")
|
vulnerabilities.append(f"Error en análisis de seguridad: {str(e)}")
|
||||||
|
|
||||||
return SecurityAnalysis(
|
return SecurityAnalysis(
|
||||||
score=security_score,
|
score=min(100, security_score),
|
||||||
features=security_features,
|
features=security_features,
|
||||||
vulnerabilities=vulnerabilities,
|
vulnerabilities=vulnerabilities,
|
||||||
spf_strict=spf_strict,
|
spf_strict=spf_strict,
|
||||||
@ -168,7 +222,7 @@ class EmailValidator:
|
|||||||
elif 'zimbra' in server_info.lower():
|
elif 'zimbra' in server_info.lower():
|
||||||
return "Zimbra"
|
return "Zimbra"
|
||||||
|
|
||||||
return "Unknown Server"
|
return "Servidor Desconocido"
|
||||||
|
|
||||||
async def validate_email(self, email: str) -> bool:
|
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):
|
if not re.match(r'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$', email):
|
||||||
@ -283,10 +337,10 @@ class EmailValidator:
|
|||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
parser = argparse.ArgumentParser(description='Email OSINT Validator')
|
parser = argparse.ArgumentParser(description='Email OSINT Validator')
|
||||||
parser.add_argument('email', help='Email to validate')
|
parser.add_argument('email', help='Email a validar')
|
||||||
parser.add_argument('-v', '--verbose', action='store_true', help='Verbose mode')
|
parser.add_argument('-v', '--verbose', action='store_true', help='Modo verbose')
|
||||||
parser.add_argument('-s', '--stealth', action='store_true', help='Stealth mode')
|
parser.add_argument('-s', '--stealth', action='store_true', help='Modo sigiloso')
|
||||||
parser.add_argument('-d', '--delay', type=int, default=0, help='Delay between queries')
|
parser.add_argument('-d', '--delay', type=int, default=0, help='Retraso entre consultas')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
validator = EmailValidator(verbose=args.verbose, stealth=args.stealth, delay=args.delay)
|
validator = EmailValidator(verbose=args.verbose, stealth=args.stealth, delay=args.delay)
|
||||||
|
Loading…
Reference in New Issue
Block a user