OSINT y reconocimiento
Ética y privacidad en OSINT: qué no deberías recopilar
Aprende finalidad, proporcionalidad, consentimiento y minimización de datos en OSINT, con nociones de LGPD y GDPR y una plantilla de plan de investigación.
Entiende cómo los logs de Certificate Transparency registran certificados TLS públicos y revisa crt.sh de un dominio tuyo, sin tocar sus hosts.
Certificate Transparency (CT) es un registro público de certificados TLS. Cuando una autoridad certificadora (CA) emite un certificado con confianza pública, lo escribe en uno o más logs de CT. Cualquiera puede leer esos logs, y nadie puede editarlos en silencio. Para quien es dueño de un dominio, esto significa un historial consultable de los certificados públicos emitidos para nombres bajo su dominio, incluidos los que nadie del equipo recuerda haber pedido.
El protocolo se especifica en la RFC 9162, "Certificate Transparency Version 2.0", publicada en diciembre de 2021. Reemplaza la especificación original, la RFC 6962. Revisa el estado antes de citarla: la RFC 9162 es un documento Experimental, no una especificación de la vía de estándares de Internet, y la propia RFC lo dice. Aun así, sigue siendo la referencia para entender cómo funcionan los logs, y los navegadores se apoyan en el mismo diseño.
CT no cifra nada y, por sí solo, no protege a un servidor. Es un mecanismo de visibilidad. Te dice qué certificados se emitieron, cuándo se registraron y qué nombres cubren. No te dice si un host está en línea, qué sirve o quién lo opera hoy.
La primera pregunta de casi todos es por qué un certificado tiene que aparecer en un log público. La respuesta es la aplicación por parte de los navegadores, y el diseño incluye un paso que la hace posible sin una dependencia circular.
El proyecto CT explica el flujo en su página de funcionamiento, en https://certificate.transparency.dev/howctworks/. De forma simplificada:
El precertificado resuelve un problema de orden. Una CA no puede obtener un SCT para el certificado final sin antes enviar algo a un log, y un navegador no debería aceptar el certificado final antes de que tenga un SCT. El precertificado rompe ese ciclo.
Los logs son append-only. Se pueden añadir entradas, pero no borrarlas, modificarlas ni insertarlas después. Cada log mantiene un árbol de Merkle, que permite a cualquiera verificar que un certificado está incluido (prueba de inclusión) y que el log solo ha crecido con el tiempo (prueba de consistencia). La sección 2 de la RFC 9162 describe el árbol. No necesitas implementarlo para usar los datos.
Dos detalles importan para quien defiende. Primero, la garantía es sobre el registro, no sobre la confianza. Un certificado registrado puede ser válido, un error o una emisión indebida, y el log no te dice cuál de las tres es. Segundo, la cobertura se limita a los certificados de CA con confianza pública. Los certificados de una PKI privada normalmente nunca llegan a un log público, así que un resultado limpio en CT no despeja todo tu entorno.
Tres usos aparecen una y otra vez.
Inventario. Los equipos crean nombres para entornos de prueba, páginas de marketing, integraciones con proveedores y proyectos viejos. Muchos de esos nombres nunca llegan a la zona DNS que alguien revisa. Una solicitud de certificado deja registro, así que CT puede mostrar nombres que tu inventario pasó por alto.
Certificados que nadie pidió. Si aparece un certificado para tu dominio y nadie del equipo lo solicitó, merece una revisión. Puede ser un proveedor actuando en tu nombre, una cuenta antigua, un proveedor que olvidaste o un atacante que tomó control de una ruta de validación. El log por sí solo no lo dice, así que escalas el caso a quienes administran el DNS y las cuentas de certificados del dominio.
Higiene del ciclo de vida. Los certificados vencidos siguen apareciendo en CT. Ese historial es útil: puedes ver qué nombres existieron y encontrar servicios retirados que todavía tienen registros DNS.
Un resultado de CT es una pista, no un veredicto. Un nombre puede estar desactualizado, pertenecer a un proveedor, ser un comodín que cubre muchos hosts o venir de una errata. Cada pista necesita la confirmación del dueño del activo.
crt.sh es una interfaz pública de búsqueda sobre logs de CT, operada por un tercero. Puedes buscar desde el navegador, o obtener JSON añadiendo output=json a la consulta. Tu consulta llega a ese servicio, así que busca solo dominios que tengas permiso de discutir. Un nombre de dominio es información pública. Un nombre de producto aún no anunciado o un hostname interno no debería escribirse en un buscador de terceros.
Existen otros servicios de búsqueda de CT. Los resultados pueden variar entre índices y entre momentos de consulta, así que anota qué servicio usaste y cuándo.
El laboratorio solo lee datos públicos de CT. No te conectas a ningún host que encuentres. Una consulta DNS de un nombre es una petición a un resolvedor, no una conexión al host, pero no vayas más allá sin permiso del dueño.
Abre https://crt.sh/?q=example.com en el navegador. Reemplaza example.com por tu dominio. Cada fila es un certificado. Lee el emisor, las fechas de validez y los nombres listados. Después prueba la forma con comodín, https://crt.sh/?q=%.example.com, que pide nombres por debajo del dominio. Compara las cantidades de ambas búsquedas.
Ejecuta:
curl -s 'https://crt.sh/?q=example.com&output=json' | jq -r '.[].name_value' | sort -u | head -50La cadena funciona en cuatro partes. curl descarga un array JSON, con un objeto por certificado. jq -r '.[].name_value' imprime el campo name_value de cada objeto, sin comillas. Algunas entradas traen varios nombres separados por saltos de línea, y sort -u elimina los duplicados. head -50 mantiene la salida legible.
jq no está instalado en mi equipo de prueba, así que no pude ejecutar esa línea aquí. Usé la misma lógica con Python 3.12, después de descargar el JSON con curl:
curl -s -o crt.json 'https://crt.sh/?q=example.com&output=json'import json
import sys
records = json.load(open(sys.argv[1], encoding="utf-8"))
names = set()
for record in records:
for name in record["name_value"].split("\n"):
names.add(name.strip())
for name in sorted(names)[:50]:
print(name)Guárdalo como crt_names.py y ejecútalo con python crt_names.py crt.json. Esta es la salida que observé el 08/11/2026. crt.sh respondió HTTP 200 con 85 registros de certificado, que contenían 12 nombres únicos:
*.example.com
AS207960 Test Intermediate - example.com
dev.example.com
emudhra-lab.example.com
example.com
m.example.com
m.testexample.com
products.example.com
[email protected]
support.example.com
[email protected]
www.example.comTres cosas llaman la atención. El comodín *.example.com cubre cualquier subdominio directo, pero no dice qué hosts existen. La línea "AS207960 Test Intermediate - example.com" no es un hostname. Parece un nombre de sujeto copiado de un certificado de CA de prueba. Las entradas [email protected] y [email protected] parecen identidades de correo, de certificados emitidos con ese fin. Un script que trate cada línea como un hostname generará ruido.
El orden que da sort -u depende de la configuración regional de tu sistema, así que puede diferir de la salida de Python. Lo que importa es el conjunto de nombres.
Exporta los nombres desde tu proveedor DNS o desde el archivo de zona, un nombre totalmente calificado por línea, en minúsculas y sin punto final. Luego compara las dos listas:
LC_ALL=C sort -u zone-names.txt > zone.sorted
LC_ALL=C sort -u ct-names.txt > ct.sorted
LC_ALL=C comm -13 zone.sorted ct.sortedcomm -13 muestra las líneas que aparecen solo en el segundo archivo. Son los nombres que aparecen en CT pero no en tu zona. Los comodines también aparecerán ahí, así que revísalos a mano. Para la comparación completa, quita el recorte [:50] del script de Python antes de generar ct-names.txt. No ejecuté este paso contra una zona real, porque no controlo la zona de example.com. La comparación funciona igual con cualquier lista de nombres.
Algunos nombres son legítimos pero viven fuera de la zona que exportaste, por ejemplo en otra zona del mismo proveedor o detrás de un CNAME. Trata "no está en mi archivo de zona" como una pregunta, no como un hallazgo.
| Hallazgo | Lo que puede significar | Siguiente paso |
|---|---|---|
| En la zona, certificado todavía válido | Esperado | Regístralo y sigue |
| Solo en CT, certificado vencido | Servicio retirado o nombre de prueba antiguo | Confirma con el dueño y actualiza el inventario |
| Entrada con comodín | Cubre nombres que quizá no listas | Revisa qué nombres tuyos protege |
| Texto libre o identidad de correo | No es un hostname | Quítalo del inventario y guárdalo en las notas |
| Nombre desconocido, certificado vigente | Posiblemente un servicio olvidado | Pregunta al dueño. No sondees el host |
| Certificado de una CA que tu equipo nunca usa | Posible emisión indebida o problema de cuenta | Escala a quien controla el DNS y las cuentas de CA |
Guarda un registro corto de cada revisión, para que otra persona pueda repetirla:
Dominio:
Consulta y fecha (UTC):
Fuente y formato (crt.sh, JSON):
Certificados devueltos:
Nombres únicos:
Nombres que coinciden con la zona:
Nombres que requieren confirmación del dueño:
Dueño contactado (quién, cuándo):Suscríbete a un monitor de CT para tu dominio. El proyecto CT señala que los monitores revisan los logs por ti y pueden avisarte cuando se registra un certificado para tu dominio. Así, una revisión puntual se convierte en una comprobación continua.
Lee las secciones 2 y 8 de la RFC 9162. La sección 2 cubre los árboles de Merkle detrás de los logs. La sección 8 trata a quienes los verifican, incluidos los monitores, que son los que más importan para tu dominio.
Después, cómo escribir tu primer informe de seguridad muestra cómo convertir una pista como esta en un texto breve que el dueño del activo puede verificar y sobre el que puede actuar.
OSINT y reconocimiento
Aprende finalidad, proporcionalidad, consentimiento y minimización de datos en OSINT, con nociones de LGPD y GDPR y una plantilla de plan de investigación.
OSINT y reconocimiento
Qué es OSINT, cómo verificar información pública, dónde están los límites éticos y cómo escribir un informe corto con evidencias.