Communitygithub.com

análisis-de-transparencia-de-certificados-para-phishing

Monitorea los registros de Transparencia de Certificados usando crt.sh y Certstream para detectar dominios de phishing y certificados sospechosos de forma temprana.

¿Qué es análisis-de-transparencia-de-certificados-para-phishing?

Esta habilidad permite a los agentes de IA y analistas de seguridad monitorear los registros de Transparencia de Certificados (CT) para detectar amenazas de phishing y certificados maliciosos de manera proactiva. Utiliza crt.sh para consultas históricas y Certstream para vigilancia en tiempo real, identificando dominios que imitan marcas legítimas, certificados no autorizados y otra infraestructura basada en certificados. Incluye flujos de trabajo completos con Python que analizan la similitud de nombres de dominio mediante Levenshtein, extraen subdominios de los registros CT y generan informes de inteligencia con recomendaciones accionables. Compatible con plataformas como Claude Code, Cursor y Codex, esta habilidad es ideal para equipos SOC que necesitan integrar la detección temprana de phishing en sus procesos de inteligencia de amenazas.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/analyzing-certificate-transparency-for-phishing

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Análisis de Transparencia de Certificados para Phishing

Resumen

La Transparencia de Certificados (CT) es un estándar de seguridad de Internet que crea un registro público, de solo adición, de todos los certificados SSL/TLS emitidos. Monitorear los registros CT permite la detección temprana de dominios de phishing que registran certificados imitando marcas legítimas, emisión de certificados no autorizados para dominios propios e infraestructura de ataques basada en certificados. Esta habilidad cubre la consulta de registros CT a través de crt.sh, monitoreo en tiempo real con Certstream, la creación de alertas automatizadas para certificados sospechosos y la integración de hallazgos en flujos de trabajo de inteligencia de amenazas.

Cuándo Usarlo

  • Al investigar incidentes de seguridad que requieran analizar la transparencia de certificados para phishing
  • Al construir reglas de detección o consultas de búsqueda de amenazas para este dominio
  • Cuando los analistas del SOC necesitan procedimientos estructurados para este tipo de análisis
  • Al validar la cobertura de monitoreo de seguridad para técnicas de ataque relacionadas

Prerrequisitos

  • Python 3.9+ con las bibliotecas requests, certstream, tldextract, Levenshtein
  • Acceso a crt.sh (https://crt.sh/) para consultas históricas de registros CT
  • Certstream (https://certstream.calidog.io/) para monitoreo en tiempo real
  • Lista de dominios de la organización y palabras clave de marca a monitorear
  • Comprensión de la estructura de certificados SSL/TLS y el proceso de emisión

Conceptos Clave

Registros de Transparencia de Certificados

Los registros CT son registros criptográficamente asegurados, auditables públicamente y de solo adición de la emisión de certificados TLS. Las AC principales (Let's Encrypt, DigiCert, Sectigo, Google Trust Services) envían todos los certificados emitidos a múltiples registros CT. A partir de 2025, Chrome y Safari requieren CT para todos los certificados de confianza pública.

Detección de Phishing mediante CT

Los atacantes registran dominios similares y obtienen certificados gratuitos (a menudo de Let's Encrypt) para que los sitios de phishing parezcan legítimos con HTTPS. El monitoreo CT detecta esto temprano porque el certificado aparece en los registros antes de que se lance la campaña de phishing, proporcionando una ventana para el bloqueo proactivo.

Base de Datos crt.sh

crt.sh es una interfaz web gratuita y una base de datos PostgreSQL operada por Sectigo que indexa registros CT. Admite búsquedas con comodín (%.example.com), consultas SQL directas y respuestas API JSON. Realiza un seguimiento de la emisión, vencimiento y revocación de certificados en todos los registros CT principales.

Flujo de Trabajo

Paso 1: Consultar crt.sh para el Historial de Certificados

import requests
import json
from datetime import datetime
import tldextract

class CTLogMonitor:
    CRT_SH_URL = "https://crt.sh"

    def __init__(self, monitored_domains, brand_keywords):
        self.monitored_domains = monitored_domains
        self.brand_keywords = [k.lower() for k in brand_keywords]

    def query_crt_sh(self, domain, include_expired=False):
        """Consultar crt.sh para certificados que coincidan con un dominio."""
        params = {
            "q": f"%.{domain}",
            "output": "json",
        }
        if not include_expired:
            params["exclude"] = "expired"

        resp = requests.get(self.CRT_SH_URL, params=params, timeout=30)
        if resp.status_code == 200:
            certs = resp.json()
            print(f"[+] crt.sh: {len(certs)} certificados para *.{domain}")
            return certs
        return []

    def find_suspicious_certs(self, domain):
        """Encontrar certificados que puedan ser intentos de phishing."""
        certs = self.query_crt_sh(domain)
        suspicious = []

        for cert in certs:
            common_name = cert.get("common_name", "").lower()
            name_value = cert.get("name_value", "").lower()
            issuer = cert.get("issuer_name", "")
            not_before = cert.get("not_before", "")
            not_after = cert.get("not_after", "")

            # Verificar coincidencias exactas de dominio (legítimas)
            extracted = tldextract.extract(common_name)
            cert_domain = f"{extracted.domain}.{extracted.suffix}"
            if cert_domain == domain:
                continue  # Certificado legítimo

            # Marcar patrones sospechosos
            flags = []
            if domain.replace(".", "") in common_name.replace(".", ""):
                flags.append("contiene cadena del dominio objetivo")
            if any(kw in common_name for kw in self.brand_keywords):
                flags.append("contiene palabra clave de marca")
            if "let's encrypt" in issuer.lower():
                flags.append("AC gratuita (Let's Encrypt)")

            if flags:
                suspicious.append({
                    "common_name": cert.get("common_name", ""),
                    "name_value": cert.get("name_value", ""),
                    "issuer": issuer,
                    "not_before": not_before,
                    "not_after": not_after,
                    "serial": cert.get("serial_number", ""),
                    "flags": flags,
                    "crt_sh_id": cert.get("id", ""),
                    "crt_sh_url": f"https://crt.sh/?id={cert.get('id', '')}",
                })

        print(f"[+] Encontrados {len(suspicious)} certificados sospechosos")
        return suspicious

monitor = CTLogMonitor(
    monitored_domains=["mycompany.com", "mycompany.org"],
    brand_keywords=["mycompany", "mybrand", "myproduct"],
)
suspicious = monitor.find_suspicious_certs("mycompany.com")
for cert in suspicious[:5]:
    print(f"  [{cert['common_name']}] Banderas: {cert['flags']}")

Paso 2: Monitoreo en Tiempo Real con Certstream

import certstream
import Levenshtein
import re
from datetime import datetime

class CertstreamMonitor:
    def __init__(self, watched_domains, brand_keywords, similarity_threshold=0.8):
        self.watched_domains = [d.lower() for d in watched_domains]
        self.brand_keywords = [k.lower() for k in brand_keywords]
        self.threshold = similarity_threshold
        self.alerts = []

    def start_monitoring(self, max_alerts=100):
        """Iniciar monitoreo en tiempo real de registros CT."""
        print("[*] Iniciando monitoreo Certstream...")
        print(f"    Observando: {self.watched_domains}")
        print(f"    Palabras clave: {self.brand_keywords}")

        def callback(message, context):
            if message["message_type"] == "certificate_update":
                data = message["data"]
                leaf = data.get("leaf_cert", {})
                all_domains = leaf.get("all_domains", [])

                for domain in all_domains:
                    domain_lower = domain.lower().strip("*.")
                    if self._is_suspicious(domain_lower):
                        alert = {
                            "domain": domain,
                            "all_domains": all_domains,
                            "issuer": leaf.get("issuer", {}).get("O", ""),
                            "fingerprint": leaf.get("fingerprint", ""),
                            "not_before": leaf.get("not_before", ""),
                            "detected_at": datetime.now().isoformat(),
                            "reason": self._get_reason(domain_lower),
                        }
                        self.alerts.append(alert)
                        print(f"  [ALERTA] {domain} - {alert['reason']}")

                        if len(self.alerts) >= max_alerts:
                            raise KeyboardInterrupt

        try:
            certstream.listen_for_events(callback, url="wss://certstream.calidog.io/")
        except KeyboardInterrupt:
            print(f"\n[+] Monitoreo detenido. {len(self.alerts)} alertas recopiladas.")
        return self.alerts

    def _is_suspicious(self, domain):
        """Verificar si el dominio es sospechoso en relación con los dominios observados."""
        for watched in self.watched_domains:
            # Coincidencia exacta de palabra clave
            watched_base = watched.split(".")[0]
            if watched_base in domain and domain != watched:
                return True

            # Distancia de Levenshtein (detección de typosquatting)
            domain_base = tldextract.extract(domain).domain
            similarity = Levenshtein.ratio(watched_base, domain_base)
            if similarity >= self.threshold and domain_base != watched_base:
                return True

        # Coincidencia de palabra clave de marca
        for keyword in self.brand_keywords:
            if keyword in domain:
                return True

        return False

    def _get_reason(self, domain):
        """Determinar por qué se marcó el dominio."""
        reasons = []
        for watched in self.watched_domains:
            watched_base = watched.split(".")[0]
            if watched_base in domain:
                reasons.append(f"contiene '{watched_base}'")
            domain_base = tldextract.extract(domain).domain
            similarity = Levenshtein.ratio(watched_base, domain_base)
            if similarity >= self.threshold and domain_base != watched_base:
                reasons.append(f"similar a '{watched}' ({similarity:.0%})")
        for kw in self.brand_keywords:
            if kw in domain:
                reasons.append(f"palabra clave de marca '{kw}'")
        return "; ".join(reasons) if reasons else "desconocido"

cs_monitor = CertstreamMonitor(
    watched_domains=["mycompany.com"],
    brand_keywords=["mycompany", "mybrand"],
    similarity_threshold=0.75,
)
alerts = cs_monitor.start_monitoring(max_alerts=50)

Paso 3: Enumerar Subdominios desde Registros CT

def enumerate_subdomains_ct(domain):
    """Descubrir todos los subdominios a partir de los registros de Transparencia de Certificados."""
    params = {"q": f"%.{domain}", "output": "json"}
    resp = requests.get("https://crt.sh", params=params, timeout=30)

    if resp.status_code != 200:
        return []

    certs = resp.json()
    subdomains = set()
    for cert in certs:
        name_value = cert.get("name_value", "")
        for name in name_value.split("\n"):
            name = name.strip().lower()
            if name.endswith(f".{domain}") or name == domain:
                name = name.lstrip("*.")
                subdomains.add(name)

    sorted_subs = sorted(subdomains)
    print(f"[+] Enumeración de subdominios CT para {domain}: {len(sorted_subs)} subdominios")
    return sorted_subs

subdomains = enumerate_subdomains_ct("example.com")
for sub in subdomains[:20]:
    print(f"  {sub}")

Paso 4: Generar Informe de Inteligencia CT

def generate_ct_report(suspicious_certs, certstream_alerts, domain):
    report = f"""# Informe de Inteligencia de Transparencia de Certificados
## Dominio Objetivo: {domain}
## Generado: {datetime.now().isoformat()}

## Resumen
- Certificados sospechosos encontrados: {len(suspicious_certs)}
- Alertas en tiempo real disparadas: {len(certstream_alerts)}

## Certificados Sospechosos (crt.sh)
| Nombre Común | Emisor | Banderas | Enlace crt.sh |
|------------|--------|-------|-------------|
"""
    for cert in suspicious_certs[:20]:
        flags = "; ".join(cert.get("flags", []))
        report += (f"| {cert['common_name']} | {cert['issuer'][:30]} "
                   f"| {flags} | [Ver]({cert['crt_sh_url']}) |\n")

    report += f"""
## Alertas en Tiempo Real de Certstream
| Dominio | Emisor | Razón | Detectado |
|--------|--------|--------|----------|
"""
    for alert in certstream_alerts[:20]:
        report += (f"| {alert['domain']} | {alert['issuer']} "
                   f"| {alert['reason']} | {alert['detected_at'][:19]} |\n")

    report += """
## Recomendaciones
1. Agregar los dominios marcados a la lista de bloqueo del sumidero DNS / proxy web
2. Enviar solicitudes de eliminación para los dominios de phishing confirmados
3. Monitorear los registros CT continuamente para nuevas registraciones de certificados
4. Implementar registros DNS CAA para restringir la emisión de certificados para tus dominios
5. Implementar DMARC para evitar la suplantación de correo electrónico desde dominios similares
"""
    with open(f"ct_report_{domain.replace('.','_')}.md", "w") as f:
        f.write(report)
    print(f"[+] Informe CT guardado")
    return report

generate_ct_report(suspicious, alerts if 'alerts' in dir() else [], "mycompany.com")

Criterios de Validación

  • Las consultas a crt.sh devuelven datos de certificados para los dominios objetivo
  • Se identifican certificados sospechosos basados en patrones de imitación
  • El monitoreo en tiempo real de Certstream detecta nuevos certificados de phishing
  • La enumeración de subdominios produce una lista completa a partir de los registros CT
  • Se generan alertas con clasificación de la razón
  • Se crea un informe de inteligencia CT con recomendaciones accionables

Referencias

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

abusing-dpapi-for-credential-access

Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys) online or offline using SharpDPAPI, SharpChrome, Mimikatz, or Impacket

abusing-shadow-credentials-for-privesc

Take over Active Directory accounts by writing attacker-controlled public keys to msDS-KeyCredentialLink (Shadow Credentials) with pyWhisker, Whisker, or Certipy, then authenticate via PKINIT to recover the target

achieving-cmmc-level-2-compliance

>-

acquiring-disk-image-with-dd-and-dcfldd

Create forensically sound bit-for-bit disk images with dd or dcfldd on a Linux forensic workstation, preserving evidence integrity through hash verification (MD5/SHA) during acquisition. Use when imaging a suspect drive, USB device, or memory card for investigation, preserving volatile disk evidence during incident response, or producing a verified copy for legal or law-enforcement proceedings before any destructive analysis.

analyzing-active-directory-acl-abuse

Detect dangerous ACL misconfigurations in Active Directory using ldap3

analyzing-android-malware-with-apktool

Perform static analysis of Android APK malware using apktool for resource decompilation, jadx for Java source recovery, and androguard for manifest inspection, dangerous permission-combination detection, and identification of obfuscated code, dynamic code loading, and reflection-based API calls. Use to statically triage a suspicious APK without executing it or to build mobile malware detection rules.

analyzing-api-gateway-access-logs

Parses API Gateway access logs (AWS API Gateway, Kong, Nginx) to detect

analyzing-apt-group-with-mitre-navigator

Query ATT&CK data with attackcti, mitreattack-python, and stix2, then build MITRE ATT&CK Navigator layers and multi-layer heatmap overlays mapping one or more APT groups

analyzing-azure-activity-logs-for-threats

Queries Azure Monitor activity logs and sign-in logs via azure-monitor-query

analyzing-bootkit-and-rootkit-samples

Analyzes bootkit and advanced rootkit malware infecting the Master

analyzing-browser-forensics-with-hindsight

Parse Chromium-based browser databases with Hindsight to extract and correlate browsing history, downloads, cookies, cached content, autofill data, saved passwords, and extensions from Chrome, Edge, Brave, Opera, and Vivaldi into a unified timeline (XLSX, JSON, or SQLite output). Use during incident response, insider-threat investigations, or criminal cases when you need to reconstruct a user

analyzing-campaign-attribution-evidence

Systematically evaluate cyber-campaign evidence to attribute an operation to a threat actor, using the Diamond Model and Analysis of Competing Hypotheses (ACH) to weigh infrastructure overlaps, TTP consistency, malware code similarity, and timing/language artifacts into confidence-weighted attribution assessments. Use when an incident investigation needs a defensible attribution confidence level.

analyzing-cloud-storage-access-patterns

Detect abnormal access in AWS S3, GCS, and Azure Blob Storage by analyzing CloudTrail Data Events, GCS audit logs, and Azure Storage Analytics for after-hours bulk downloads, new-IP access, and API-call spikes (e.g. GetObject) via statistical baselines and time-series anomaly detection. Use when investigating suspected cloud data exfiltration or building related detection rules.

analyzing-cobalt-strike-beacon-configuration

Extract and analyze Cobalt Strike beacon configuration from PE files

analyzing-cobaltstrike-malleable-c2-profiles

Parse and analyze Cobalt Strike Malleable C2 profiles with dissect.cobaltstrike (profiles and beacon-payload configs) and pyMalleableC2 (AST parsing) to extract HTTP/DNS transforms, URIs, headers, sleep/jitter, and injection behavior, then generate network detection signatures. Use when reverse-engineering a captured malleable profile or building detections against Cobalt Strike Beacon traffic.

analyzing-command-and-control-communication

Analyzes malware C2 communication over HTTP, HTTPS, DNS, and custom

analyzing-cyber-kill-chain

Analyzes intrusion activity against the Lockheed Martin Cyber Kill Chain

analyzing-disk-image-with-autopsy

Perform comprehensive forensic analysis of raw (dd), E01, or AFF disk images with Autopsy and The Sleuth Kit, recovering deleted files, examining metadata and embedded artifacts, keyword searching, and building investigation timelines with visual reports. Use for structured analysis of a forensic disk image or when stakeholders need visual reports from evidence.

analyzing-dns-logs-for-exfiltration

Analyzes DNS query logs to detect data exfiltration via DNS tunneling,

analyzing-docker-container-forensics

Investigate compromised Docker containers by analyzing images, layers,

Skills relacionados