feat(infra): auto-commit con 88 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
"""Orquestador OSINT pasivo: genera candidatos de enriquecimiento de una persona.
|
||||
|
||||
Compone funciones atomicas del registro (`guess_email_formats`,
|
||||
`enumerate_username_sites`, `build_search_dorks`) para producir candidatos OSINT
|
||||
de una persona SIN contactar ni atacar al objetivo. Los dorks se generan pero
|
||||
NO se ejecutan.
|
||||
|
||||
Funcion IMPURA: `enumerate_username_sites` consulta servicios publicos (red).
|
||||
"""
|
||||
|
||||
from cybersecurity import (
|
||||
build_search_dorks,
|
||||
enumerate_username_sites,
|
||||
guess_email_formats,
|
||||
)
|
||||
|
||||
# Dominios de correo comunes usados cuando el caller no aporta dominios propios.
|
||||
_COMMON_EMAIL_DOMAINS = ("gmail.com", "outlook.com")
|
||||
|
||||
|
||||
def enrich_person_passive(
|
||||
nombre: str,
|
||||
apellidos: str,
|
||||
dominios: list | None = None,
|
||||
usernames: list | None = None,
|
||||
) -> dict:
|
||||
"""Genera candidatos OSINT pasivos para una persona.
|
||||
|
||||
Para cada dominio aportado (o los dominios comunes gmail/outlook si no se da
|
||||
ninguno) genera los formatos de email candidatos. Para cada username
|
||||
aportado comprueba en que sitios publicos existe. Ademas genera dorks de
|
||||
busqueda de tipo persona (que NO se ejecutan, solo se devuelven).
|
||||
|
||||
Args:
|
||||
nombre: nombre de pila de la persona.
|
||||
apellidos: apellido(s) de la persona.
|
||||
dominios: lista de dominios de correo donde buscar formatos de email.
|
||||
Si es None o vacia, se usan los dominios comunes gmail/outlook.
|
||||
usernames: lista de usernames a comprobar en sitios publicos. Si es None
|
||||
o vacia, no se realiza ninguna comprobacion de username.
|
||||
|
||||
Returns:
|
||||
dict con las claves:
|
||||
- email_candidates: lista de emails candidatos (no verificados).
|
||||
- username_hits: lista de resultados de enumerate_username_sites por
|
||||
cada username comprobado.
|
||||
- dorks: lista de dorks de busqueda generados (no ejecutados).
|
||||
|
||||
Raises:
|
||||
ValueError: si nombre y apellidos estan ambos vacios.
|
||||
"""
|
||||
if not (nombre or "").strip() and not (apellidos or "").strip():
|
||||
raise ValueError("nombre y apellidos no pueden estar ambos vacios")
|
||||
|
||||
target_domains = [d for d in (dominios or []) if d] or list(_COMMON_EMAIL_DOMAINS)
|
||||
|
||||
email_candidates: list = []
|
||||
for dominio in target_domains:
|
||||
candidates = guess_email_formats(nombre, apellidos, dominio)
|
||||
if candidates:
|
||||
email_candidates.extend(candidates)
|
||||
# Deduplicar preservando orden.
|
||||
email_candidates = list(dict.fromkeys(email_candidates))
|
||||
|
||||
username_hits: list = []
|
||||
for username in usernames or []:
|
||||
if not username:
|
||||
continue
|
||||
hits = enumerate_username_sites(username)
|
||||
username_hits.append({"username": username, "hits": hits})
|
||||
|
||||
target = f"{nombre} {apellidos}".strip()
|
||||
dorks = build_search_dorks(target, "persona")
|
||||
|
||||
return {
|
||||
"email_candidates": email_candidates,
|
||||
"username_hits": username_hits,
|
||||
"dorks": dorks,
|
||||
}
|
||||
Reference in New Issue
Block a user