--- id: "0037" title: "IoC regex extractor (cybersecurity)" status: completado type: feature domain: [] scope: multi-app priority: alta depends: [] blocks: [] related: [] created: 2026-05-17 updated: 2026-05-17 tags: [] --- # 0037 — IoC regex extractor (cybersecurity) ## Metadata | Campo | Valor | |-------|-------| | **ID** | 0037 | | **Estado** | pendiente | | **Prioridad** | alta | | **Tipo** | feature — Python (`python/functions/cybersecurity/`) | ## Dependencias Ninguna. Es la pieza de mayor ROI del plan: regex puros, sin modelos, 100% precision para IoCs tecnicos. Complementa (no sustituye) a GLiNER, que es malo para identificadores tecnicos. **Desbloquea:** mejor precision del pipeline hibrido (0040). Permite filtrar IoCs antes del paso LLM/NER en cualquier flujo OSINT. --- ## Objetivo Familia de funciones puras que extraen IoCs (Indicators of Compromise) de texto via regex. Cada una retorna `list[dict]` con `value`, `start`, `end` y `type` para que el caller pueda construir `EntityCandidate` o `triple` sin reparsing. ## Funciones a crear | Function ID | Que extrae | |---|---| | `extract_iocs_py_cybersecurity` | Pipeline pure: corre todos los extractors abajo y devuelve lista unificada con `type` | | `extract_ip_addresses_py_cybersecurity` | IPv4 + IPv6, valida rangos (no `999.999.999.999`) | | `extract_emails_py_cybersecurity` | RFC 5322 simplificado | | `extract_domains_py_cybersecurity` | FQDNs con TLD valido (lista compilada) | | `extract_file_hashes_py_cybersecurity` | MD5 (32 hex), SHA1 (40), SHA256 (64), SHA512 (128) — devuelve `algorithm` | | `extract_crypto_wallets_py_cybersecurity` | BTC (legacy + bech32), ETH (0x + 40 hex con checksum opcional) | | `extract_cve_ids_py_cybersecurity` | `CVE-YYYY-NNNN+` | | `extract_mac_addresses_py_cybersecurity` | `xx:xx:xx:xx:xx:xx` y `xx-xx-xx-xx-xx-xx` | | `extract_phone_numbers_py_cybersecurity` | E.164 + formatos comunes ES/EU | `extract_urls_py_cybersecurity` ya existe — no duplicar. ## Contrato ```python def extract_(text: str) -> list[dict]: """ Returns: [{"value": str, "start": int, "end": int, "type": ""}, ...] """ ``` `extract_iocs_py_cybersecurity` (pipeline) compone los anteriores y unifica resultados: ```python def extract_iocs( text: str, types: list[str] | None = None, # None = todos ) -> list[dict] ``` ## Pureza Todas `purity: pure`. Solo regex compilado y validacion estructural. Sin red, sin disco, deterministas. ## Deliverables - 9 archivos `.py` + 9 `.md` en `python/functions/cybersecurity/` - 1 archivo `.py` adicional para el pipeline `extract_iocs.py` - Tests unitarios en `python/functions/cybersecurity/tests/test_extract_iocs.py` con corpus pequeño de positivos y negativos por tipo - Frontmatter completo: `params`, `output`, `domain: cybersecurity`, `purity: pure` ## Validacion ```bash ./fn run extract_iocs_py_cybersecurity # corre tests ./fn show extract_iocs_py_cybersecurity # verifica frontmatter ``` Bench informal: 1 MB de texto < 100 ms por extractor en CPU. ## Notas - No validar TLDs con DNS — solo lista estatica de TLDs validos (publicsuffix opcional pero no obligatorio). - Devolver offsets `start`/`end` siempre — los necesitan los issues 0038-0040 para reconciliar con spans de GLiNER. - IPs privadas (10.x, 192.168.x) se extraen igual; el filtrado de relevancia es del caller, no del extractor.