--- name: enum_subdomains_crtsh kind: function lang: py domain: cybersecurity version: "1.0.0" purity: impure signature: "def enum_subdomains_crtsh(dominio: str, timeout_s: float = 20.0) -> list" description: "Enumeracion OSINT pasiva de subdominios desde Certificate Transparency (crt.sh). Consulta https://crt.sh/?q=%25.&output=json con http_get_json, extrae name_value de cada certificado, separa por saltos de linea, deduplica, filtra wildcards (*.) y devuelve la lista ordenada de subdominios unicos. Pasivo: no toca al objetivo, consulta logs CT publicos." tags: [osint-passive, subdomains, crtsh, certificate-transparency, recon, cybersecurity] params: - name: dominio desc: "Dominio base a enumerar, ej. organic-machine.com. Vacio lanza RuntimeError." - name: timeout_s desc: "Segundos maximo de espera de la peticion HTTP a crt.sh (default 20.0)." output: "Lista ordenada de subdominios unicos (en minusculas, sin wildcards) que aparecen en certificados emitidos para el dominio. Lista vacia si crt.sh no devuelve resultados." uses_functions: ["http_get_json_py_infra"] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] tested: true tests: ["test_dedup_y_orden", "test_filtra_wildcards", "test_respuesta_vacia", "test_respuesta_no_lista_lanza_error", "test_dominio_vacio_lanza_error"] test_file_path: "python/functions/cybersecurity/enum_subdomains_crtsh_test.py" file_path: "python/functions/cybersecurity/enum_subdomains_crtsh.py" --- ## Ejemplo ```python import sys, os sys.path.insert(0, os.path.join("python", "functions")) from cybersecurity import enum_subdomains_crtsh subs = enum_subdomains_crtsh("organic-machine.com") for s in subs: print(s) # api.organic-machine.com # mail.organic-machine.com # organic-machine.com # www.organic-machine.com ``` ## Cuando usarla Usala para descubrir la superficie de subdominios de un objetivo sin enviarle trafico: los logs de Certificate Transparency listan todos los nombres para los que se han emitido certificados TLS. Complementa a `dns_records` (resolucion) y `whois_lookup` (registro) en el reconocimiento pasivo inicial. ## Gotchas - Es OSINT **pasivo**: consulta los logs CT publicos via crt.sh, NO toca al dominio objetivo ni resuelve los subdominios encontrados (algunos pueden estar muertos o no resolver). - crt.sh suele ir lento o rate-limitear bajo carga; para dominios grandes la respuesta puede tardar varios segundos o agotar el `timeout_s`. Subir el timeout o reintentar si falla. - Solo encuentra subdominios que han tenido certificado TLS emitido y logueado en CT; subdominios internos sin certificado publico no apareceran. - Los wildcards (`*.dominio`) se filtran porque no son hosts concretos. - crt.sh devuelve un array JSON (no un objeto); por eso si la respuesta no es una lista se lanza `RuntimeError`. - Puede incluir subdominios de niveles arbitrarios y dominios relacionados que compartieron certificado SAN; revisa la salida antes de usarla como verdad.