Files
fn_registry/dev/issues/0037-ioc-regex-extractor.md
T
egutierrez b837b8281a docs(issues): añadir 0037-0040 — extraccion de entidades y relaciones
- 0037: IoC regex extractor (IP, email, dominio, hash, wallet, CVE, MAC)
- 0038: GLiNER entity extractor (zero-shot NER multilingue)
- 0039: GLiREL relation extractor (zero-shot triplets)
- 0040: pipeline hibrido extraccion grafos (regex + GLiNER + GLiREL + LLM fallback)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 18:41:44 +02:00

83 lines
3.1 KiB
Markdown

# 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_<ioc_type>(text: str) -> list[dict]:
"""
Returns:
[{"value": str, "start": int, "end": int, "type": "<ioc_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.