fad4006f60
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
98 lines
3.3 KiB
Markdown
98 lines
3.3 KiB
Markdown
---
|
|
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_<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.
|