
threat-finder v0.3.0
Escáner de vulnerabilidades en tiempo de ejecución: detecta CVEs en los servicios que realmente se ejecutan en un host y los clasifica según su exposición a la red.
OffSeq Threat Finder
threat-finder encuentra el software vulnerable realmente en ejecución en un host — no lo que afirma un manifiesto — y te indica qué hallazgos son accesibles desde la red.
Resuelve cada servicio en ejecución (y, con --scope all, cada paquete del sistema operativo instalado) a un Package-URL exacto y lo compara con el catálogo de OffSeq Radar usando reglas de versionado nativas del ecosistema, de modo que las compilaciones con backport/corregidas no se marcan falsamente.
Vulnerability summary (highest risk first):
openssh-server@1:8.9p1-3ubuntu0.6 — 1 finding(s) [PUBLIC tcp 0.0.0.0:22]
[ACT-NOW 92] HIGH CVE-2024-6387 [KEV] regreSSHion: remote code execution in OpenSSH
→ fix: 1:8.9p1-3ubuntu0.10 https://radar.offseq.com/threat/…
[email protected] — 1 finding(s)
[SCHEDULE 41] MED CVE-2023-44487 HTTP/2 Rapid Reset
2 confirmed finding(s) across 2 asset(s); 1 exposed, 1 known-exploited.
Instalación
brew install offseq/tap/threat-finder # Homebrew (macOS/Linux), prebuilt
cargo binstall threat-finder # prebuilt binary, no toolchain
cargo install threat-finder # from source
Los archivos precompilados para Linux/macOS (x86_64 + arm64) y Windows (x86_64) están en la página de lanzamientos. Se requiere Rust ≥ 1.87 para compilar desde el código fuente. Se admiten Linux, macOS, los BSD y Windows.
Inicio rápido
export OFFSEQ_API_KEY=... # from https://radar.offseq.com/console
threat-finder
Escanea los servicios en ejecución, imprime un resumen ordenado por riesgo y escribe el informe JSON completo en /tmp/threats.json. Añade --scope all para escanear también todos los paquetes del sistema operativo instalados.
Uso
threat-finder [OPTIONS]
| Flag | Descripción |
|---|---|
-o, --output <PATH> | Escribe el informe JSON en PATH (por defecto: pregunta, o /tmp/threats.json) |
--json | Imprime el informe JSON en stdout en lugar de un archivo |
--scope <SCOPE> | running (predeterminado) o all (+ cada paquete del sistema operativo instalado) |
--severity <LEVEL> | Solo informa de hallazgos en/por encima de critical|high|medium|low |
--strict | Descarta los hallazgos sin confirmación de coordenadas (solo informa de los confirmados) |
--fail-on <WHAT> | Sale con 5 si existen hallazgos coincidentes: any|critical|high|medium|low|kev|exposed |
--sarif <PATH> | También escribe un informe SARIF 2.1.0 (para interfaces de code-scanning) |
--include <GLOB> / --exclude <GLOB> | Filtra activos por nombre glob (repetible) |
-q, --quiet | Suprime el banner, el progreso y el resumen |
--no-color | Desactiva los colores ANSI |
-y, --yes | Asume los valores predeterminados, nunca pregunta (CI/cron) |
--reset | Vuelve a introducir la clave API, ignorando la guardada |
--register | Registra el host escaneado en Radar para monitorización continua (sin preguntar) |
--no-register | No registra ni pregunta sobre la monitorización en esta ejecución |
--host-name <NAME> | Nombre de host descriptivo para enviar con un registro |
--unregister | Elimina el inventario de este host de Radar y sale |
--windows-missing-updates | (Windows) También lista las actualizaciones de seguridad pendientes del Agente de Windows Update (escaneo en línea; ejecutar como administrador) |
-h, --help / -V, --version | Ayuda / versión |
# CI: solo hallazgos high+, JSON a stdout, sin preguntas
OFFSEQ_API_KEY=… threat-finder --yes --json --severity high > report.json
# Falla la compilación solo cuando un servicio expuesto a la red tiene un CVE con exploit conocido
OFFSEQ_API_KEY=… threat-finder --yes --quiet --fail-on exposed
Códigos de salida: 0 correcto · 1 error de búsqueda/IO · 2 sin clave API · 3 sistema operativo no compatible · 4 límite de tasa/cuota, o se requiere acceso a la API (actualización necesaria) · 5 umbral --fail-on alcanzado.
Clave API (obtén una en la Consola Radar), se resuelve en este orden:
- Variable de entorno
OFFSEQ_API_KEY(lo mejor para CI/cron). - La clave guardada en
$XDG_CONFIG_HOME/offseq-rust/config.toml(0600), a menos que se indique--reset. - Una solicitud interactiva y oculta en una TTY — luego se guarda para la próxima vez.
Sin modo interactivo (--yes / sin TTY) y sin clave disponible se sale con 2.
Define OFFSEQ_CONFIG_DIR para anular la ubicación de la configuración (por defecto: el directorio de configuración por usuario del SO) — útil para contenedores/CI que necesitan una ruta determinista.
Cómo funciona
Coincidencia por coordenadas exactas. Cada activo se convierte en un purl que lleva su versión completa (epoch + revisión de la distribución) y un calificador ?distro=, p. ej.
pkg:deb/ubuntu/openssh-server@1:8.9p1-3ubuntu0.6?distro=jammy. El inventario se compara en llamadas por lotes POST /match/batch (una solicitud por fragmento del tamaño de un nivel) en el servidor, con reglas de versionado nativas del ecosistema (dpkg/rpm/apk/semver) — de modo que una compilación con backport y corregida como 1.18.0-6+deb11u3 no se marca correctamente, y no hay adivinanzas de versiones en el cliente. Los hallazgos se dividen según el indicador confirmed de la API: los hallazgos confirmados se notifican; las coincidencias de coordenadas cuya versión no puede confirmarse se muestran por separado como no confirmados / triaje (excluidos del recuento, de byCve y de --fail-on; elimínalos con --strict).
Correlación de exposición a la red. Los escáneres de manifiestos (Trivy, Grype, osv-scanner) leen listas de paquetes; los escáneres externos (Nessus, OpenVAS) necesitan un segundo host. Esta herramienta asigna el proceso de cada servicio en ejecución a los sockets en los que está escuchando (/proc/net en Linux, lsof en los otros Unix, Get-NetTCPConnection / netstat en Windows) y clasifica la alcanzabilidad: loopback / private / public. Un servicio vulnerable en 0.0.0.0 es un riesgo muy distinto de uno en 127.0.0.1: los hallazgos se ordenan con los expuestos primero y --fail-on exposed condiciona el CI exactamente a eso. No se envían paquetes. Los hallazgos también incluyen KEV de CISA y EPSS.
Priorización según exposición. Cada hallazgo recibe un riskScore (0–100) y una banda de decision estilo SSVC — act-now · soon · schedule · track — combinada a partir de la severidad, EPSS, KEV y la exposición a la red del activo propietario. El resumen encabeza cada línea con una insignia estilo [ACT-NOW 92] y ordena por ella, de modo que los pocos problemas públicos y con exploit conocido floten a la cima de un host ruidoso. La puntuación usa la misma fórmula localmente y en el servidor (la vista de monitorización de Radar añade un pequeño bonus cuando un hallazgo KEV ha superado su fecha límite — una fecha que la CLI no tiene), y aparece en --json y SARIF (properties).
Monitorización continua
Un escaneo puntual es un momento en el tiempo. Registra un host una vez y Radar seguirá vigilando: cuando un CVE recién publicado afecta a una de sus coordenadas, recibes una alerta (correo + Consola), priorizada por exposición — sin necesidad de volver a escanear.
Después de un escaneo interactivo, la herramienta pregunta:
Add these 42 services to Radar for continuous monitoring & alerts? [Y/n/never]
Y registra este host; n omite esta ejecución; never recuerda tu elección (se guarda en la configuración y no se te volverá a preguntar). En un nuevo escaneo también informa de deriva (+added / -removed / ~changed) y de cualquier hallazgo nuevo desde tu último escaneo. Gestiona tus hosts — activa/desactiva la monitorización, consulta hallazgos, da de baja — en Inventory de la Consola Radar.
Para automatización, omite la pregunta: --register registra de forma no interactiva (desactivado por defecto en CI), --no-register opta por no participar, --host-name <NAME> etiqueta el host y --unregister lo elimina. Un id estable por host y tu preferencia sobre la pregunta viven en $XDG_CONFIG_HOME/offseq-rust/config.toml. El registro nunca cambia el código de salida — un contratiempo de monitorización no hará fallar tu escaneo. Requiere un plan Basic/Pro/Enterprise (o Consola Pro).
Alcance y cobertura
--scope running (predeterminado) escanea los servicios en vivo — el conjunto pequeño y de alta señal cuya exposición puede correlacionarse. --scope all además enumera cada paquete del sistema operativo instalado (dpkg/rpm/pacman/apk/brew/pkg/pkg_info), expandiendo la superficie comparada 10–50×. Un paquete que también respalda un proceso en ejecución y expuesto conserva esa exposición (los activos se deduplican y fusionan por coordenada). El kernel se cubre como su paquete (linux-image…) con --scope all.
--scope allpuede producir cientos–miles de paquetes. En el nivel gratuito (15 consultas/hora) esto provocará limitación de tasa; la herramienta avisa cuando el inventario supera el presupuesto. (Las consultas ya van por lotes; una caché local de resultados está en la hoja de ruta.)
Soporte por sistema operativo
| SO | Descubrimiento | Fuente de coordenadas |
|---|---|---|
| Linux (systemd) | ListUnits → /proc/<pid>/exe | dpkg / rpm / pacman / apk |
| Linux (SysV/OpenRC) | service --status-all / rc-status | base de datos de paquetes |
| macOS | launchctl list → ps (solo terceros) | Homebrew |
| FreeBSD / DragonFly | service -e | pkg |
| OpenBSD | rcctl ls started | pkg_info |
| NetBSD | estado de /etc/rc.d | pkg_info |
| Solaris / illumos | svcs → svcprop | sonda (--version) |
| Windows | Win32_Service → Get-NetTCPConnection / netstat | registro / winget / Appx / Chocolatey / Scoop → CPE; npm / pip / dotnet → purl; la compilación del SO → CPE |
Cuando ningún paquete es propietario de un binario, la versión recurre a una sonda --version endurecida (solo ruta absoluta, entorno saneado). En macOS, los servicios del sistema de Apple (com.apple.*, rutas protegidas por SIP) se omiten — están cubiertos por la versión del SO, y sondear cientos de ellos no tiene sentido.
En Windows, todo se recopila mediante el powershell.exe integrado (sin runtime adicional, sin administrador para el inventario principal). Las aplicaciones instaladas se asignan a CPE de NVD mediante una tabla de nombres curada (las aplicaciones no asignadas recurren a una búsqueda por nombre en lugar de una suposición errónea); la edición/compilación del SO se convierte en un CPE de SO con calificador de características (p. ej. windows_11_23h2); y --windows-missing-updates añade un aviso opcional del Agente de Windows Update sobre parches de seguridad pendientes.
Salida
JSON, con claves deterministas (ordenadas) y sin marca de tiempo, para que los informes se diferencien limpiamente:
services—pkg@version→ hallazgos confirmados (cveId,severity,cvssScore,epss,kev,riskScore,decision,confirmed,matchedRange,matchBasis,fixedVersions,remediation,cwes,references,radarUrl), primero los de mayor riesgo.unconfirmed— coincidencias de coordenadas cuya versión no pudo confirmarse (triaje).assets—pkg@version→{ exe, versionSource, exposed, reachability, listeners }(versionSource=package-db|probe;reachabilitycubre TCP y UDP).byCve— cada CVE agrupado en todos los activos afectados ("parchea una vez, arregla muchos").errors— fallos de búsqueda por activo, de modo que un fallo nunca se lea como "limpio".registration— presente cuando la ejecución registró el host:host_id,monitoring,drift,summary,newSinceLastCount.meta—{ tool, version, schemaVersion }(schemaVersion2).
También hay disponible un informe SARIF 2.1.0 (--sarif) para interfaces de code-scanning.
El ecosistema OffSeq
| OffSeq | Auditorías de seguridad en la UE, monitorización de amenazas, CISO como servicio, cumplimiento NIS2 |
| Radar | Inteligencia de amenazas en tiempo real — el catálogo contra el que compara threat-finder |
| Consola Radar | Suscripciones, feeds personalizados y tu OFFSEQ_API_KEY |
| API Radar | Documentación REST para el endpoint /match usado aquí |
| Radar Threats | Base de datos buscable de CVE / malware / actores de amenazas |
| Radar Feeds | Feeds personalizados que agregan CISA, CIRCL, ThreatFox, … |
| Radar Pricing | Desde el nivel gratuito hasta Enterprise |
| Breach | Monitorización de filtraciones de datos y credenciales expuestas en la dark web |
| Veil | Esteganografía PNG del lado del cliente (AES-256-GCM) |
| Guard | Analista de seguridad y cumplimiento web con IA |
| Training | Cursos de seguridad y privacidad acreditados por PECB |
Desarrollo
cargo build --release
cargo test # unit tests
cargo test -- --ignored # + macOS live-discovery smoke test
cargo clippy --all-targets
El motor es una crate de biblioteca (find_threats) con una abstracción Collector (servicios en ejecución y paquetes del SO hoy; lockfiles / contenedores / SBOM a continuación), de modo que el binario es una CLI delgada sobre ella.
Licencia
Con doble licencia bajo MIT o Apache-2.0, a tu elección.