osquery:
consulta tu parque como si fuera una base de datos
Serie Blue Team | unfantasmaenelsistema.com
Cuando alguien pregunta «¿en cuántos equipos está instalada esta versión vulnerable de una librería?» o «¿qué máquinas tienen ahora mismo un proceso escuchando en un puerto raro?», la respuesta suele ser un script distinto para Windows, otro para Linux, otro para macOS, y varios días de recopilar salidas en una hoja de cálculo. osquery cambia esa foto: expone el sistema operativo como si fuera una base de datos relacional, y responde a esas preguntas con una consulta SQL que funciona igual en las tres plataformas.
Es un proyecto open source nacido en Facebook en 2014 y hoy bajo la Linux Foundation. Este artículo explica el modelo mental (el SO como tablas), la diferencia entre lanzar consultas puntuales y programar packs de vigilancia, cómo funciona el demonio y su registro de eventos, cómo se gestiona una flota entera con Fleet, qué consultas aportan valor real para inventario y para detección, y —tan importante como lo anterior— qué cosas osquery no hace.
Qué aprenderás en este artículo
El modelo de osquery: el sistema operativo representado como tablas SQL que puedes consultar · Consultas ad-hoc con osqueryi frente a packs programados con osqueryd · Cómo funciona el registro de resultados, la diferencia entre snapshot y differential, y la vista de eventos · Gestión de flota con Fleet: desplegar consultas, recoger resultados y encajarlo con el SIEM · Consultas útiles para inventario y para detección, con ejemplos por tabla · Los límites: osquery no es un EDR, no bloquea nada y solo ve el instante en que pregunta
1. El modelo: el sistema operativo como tablas
La idea central de osquery es sencilla y potente. En lugar de aprenderte `tasklist`, `ps`, `netstat`, `wmic`, `launchctl`, `crontab -l` y una docena más de comandos con formatos de salida distintos en cada sistema, osquery expone toda esa información como tablas que se consultan con SQL estándar (un dialecto de SQLite). Preguntar por los procesos en ejecución es `SELECT * FROM processes`; preguntar por los puertos a la escucha es `SELECT * FROM listening_ports`; y unir ambas cosas para saber qué binario abre cada puerto es un simple JOIN.
Las tablas son virtuales: no hay datos almacenados esperando a ser leídos. Cuando lanzas la consulta, osquery ejecuta en ese momento las llamadas al sistema necesarias para poblar las filas y te devuelve el resultado. Hay más de 250 tablas; unas son multiplataforma y otras específicas de un SO.
| Tabla | Qué contiene | Uso típico |
|---|---|---|
| processes | Procesos en ejecución: pid, nombre, ruta del binario, línea de comandos, hash, uid, directorio de trabajo | Inventario de lo que corre; base de casi toda detección |
| listening_ports | Puertos TCP/UDP a la escucha y el pid que los abre | Servicios expuestos, listeners inesperados |
| process_open_sockets | Conexiones de red por proceso (local y remota) | Beaconing, conexiones salientes anómalas |
| users / logged_in_users | Cuentas locales y sesiones activas | Cuentas nuevas, sesiones fuera de horario |
| startup_items | Programas que arrancan con el sistema (multiplataforma) | Persistencia |
| scheduled_tasks (Win) / crontab (nix) | Tareas programadas | Persistencia por tareas |
| services (Win) / systemd_units (Linux) / launchd (mac) | Servicios y unidades | Persistencia por servicio |
| chrome_extensions / firefox_addons | Extensiones de navegador instaladas por usuario | Extensiones maliciosas o no aprobadas |
| file / hash | Metadatos y hash de rutas que le indiques | Verificar integridad de ficheros clave |
| os_version / system_info / kernel_info | Versión de SO, hardware, kernel | Inventario y cumplimiento |
| deb_packages / rpm_packages / programs / homebrew_packages | Software instalado | Gestión de vulnerabilidades: ¿quién tiene la versión X? |
Explora el esquema desde dentro
En osqueryi, `.tables` lista todas las tablas, `.schema processes` muestra las columnas de una, y `SELECT * FROM osquery_schema` es consultable como cualquier otra. La documentación oficial en osquery.io/schema es la referencia completa, filtrable por sistema operativo.
2. osqueryi: la consola interactiva
osqueryi es un binario autónomo que abre una consola SQL. No necesita el demonio ni permisos de administrador para las consultas básicas (aunque muchas tablas devuelven más columnas si se ejecuta con privilegios). Es la herramienta para explorar, para responder a una pregunta puntual durante un incidente y para escribir y depurar consultas antes de programarlas.
$ osqueryi
-- Procesos cuyo binario ya no existe en disco (posible proceso inyectado o borrado)
SELECT pid, name, path FROM processes WHERE on_disk = 0;
-- Qué proceso abre cada puerto a la escucha
SELECT p.name, p.path, lp.address, lp.port, lp.protocol
FROM listening_ports lp JOIN processes p ON lp.pid = p.pid
WHERE lp.address NOT IN ('127.0.0.1', '::1');
-- Conexiones salientes establecidas y el binario que las mantiene
SELECT p.name, p.path, s.remote_address, s.remote_port
FROM process_open_sockets s JOIN processes p ON s.pid = p.pid
WHERE s.remote_address NOT LIKE '10.%' AND s.remote_address NOT LIKE '192.168.%';El resultado se puede pedir en formato tabla (por defecto), en JSON (`–json`) o en línea (`.mode line`), lo que hace trivial encadenar osqueryi con `jq` en un script de triaje. Para una consulta única sin abrir la consola: `osqueryi –json «SELECT …»`.
3. osqueryd: el demonio y las consultas programadas
osqueryd es el proceso que corre de forma permanente en cada equipo. Su trabajo es ejecutar un conjunto de consultas en un calendario —la *schedule*— y registrar los resultados. Aquí es donde osquery pasa de ser una herramienta de consulta a ser una fuente de telemetría continua.
3.1 Snapshot frente a differential
Cada consulta programada tiene un intervalo (por ejemplo, 3600 segundos). En cada ejecución osquery compara el resultado con el de la vez anterior y, por defecto, registra solo las diferencias: qué filas se han añadido y qué filas han desaparecido. Es el modo *differential*, y es lo que hace viable programar `SELECT * FROM processes` sin generar gigabytes: en régimen normal, la mayoría de ejecuciones no produce ninguna línea de log. El modo *snapshot* registra el resultado completo cada vez y se reserva para consultas de inventario que quieres tener enteras periódicamente.
// /etc/osquery/osquery.conf (fragmento)
{
"options": {
"schedule_splay_percent": 10,
"disable_events": false
},
"schedule": {
"procesos": { "query": "SELECT pid,name,path,cmdline,uid FROM processes;", "interval": 300 },
"listeners": { "query": "SELECT pid,address,port,protocol FROM listening_ports;", "interval": 300 },
"usuarios": { "query": "SELECT * FROM users;", "interval": 3600, "snapshot": true },
"inventario_so": { "query": "SELECT * FROM os_version;", "interval": 86400, "snapshot": true }
}
}3.2 Dónde acaban los resultados
osqueryd escribe los resultados como líneas JSON en un fichero (`osqueryd.results.log`), y desde ahí cualquier recolector de logs los sube al SIEM. También puede enviarlos por syslog o, en despliegues gestionados, entregarlos directamente al servidor de la flota. Cada línea lleva el nombre de la consulta, la acción (`added` / `removed` / `snapshot`), la fila y el identificador del host.
El intervalo es un compromiso, no un detalle
Un `interval` de 3600 sobre procesos significa que un proceso que arranca y muere en 20 minutos puede no aparecer nunca en el modo differential. Para procesos y red, intervalos cortos (60-300 s) o, mejor, las tablas de eventos. Para inventario de software, un intervalo diario sobra.
4. Las tablas de eventos: cubrir lo que pasa entre consultas
El punto débil del modelo de consulta periódica es evidente: osquery solo ve el estado en el instante en que pregunta. Para cerrar ese hueco existen las tablas de eventos, que se apoyan en los subsistemas de auditoría del propio SO —Audit en Linux, ETW y otros en Windows, EndpointSecurity en macOS— y acumulan lo ocurrido para servirlo en la siguiente consulta.
| Tabla de eventos | Plataforma | Qué captura |
|---|---|---|
| process_events | Linux, macOS | Cada ejecución de proceso (execve): binario, argumentos, padre, uid |
| socket_events | Linux, macOS | Cada conexión de red creada por un proceso |
| file_events | Linux, Windows, macOS | Cambios en rutas o directorios que declares vigilados (FIM) |
| user_events | Linux | Eventos de sesión y de autenticación del subsistema audit |
| windows_events / powershell_events | Windows | Canales de eventos de Windows y bloques de script de PowerShell |
Las tablas de eventos requieren activar el sistema de publicación (`disable_events: false`) y, en Linux, que osquery gestione el socket de audit (`audit_allow_config`, `audit_allow_process_events`). Eso implica el mismo conflicto por el socket de audit que ya afecta a auditd y a otros agentes: en un host solo un proceso debe ser el dueño. Con eventos activados, `SELECT * FROM process_events WHERE time > …` te da un histórico de ejecuciones aunque la consulta corra una vez por minuto.
-- Vigilar un directorio con file_events: primero se declara en la config
// "file_paths": { "binarios_criticos": [ "/usr/bin/%%", "/etc/%%" ] }
-- y luego se consulta la tabla de eventos acumulados
SELECT target_path, action, category, time
FROM file_events WHERE time > (strftime('%s','now') - 3600);
-- Ejecuciones cuyo proceso padre es un servicio de red (Linux/macOS)
SELECT path, cmdline, parent, time FROM process_events
WHERE path IN ('/bin/sh','/bin/bash','/usr/bin/python3');5. Gestión de flota: de un equipo a diez mil
osquery de serie no trae un servidor central: cada demonio lee su fichero de configuración y escribe su log local. Para operar una flota se usa un plano de control. El de referencia hoy es Fleet (fleetdm.com), open source, que habla el protocolo TLS nativo de osquery.
- Distribución de configuración: Fleet entrega a cada host su schedule, sus packs y sus opciones, organizados por equipos (por ejemplo, servidores Linux vs. portátiles de usuario), sin tocar ficheros máquina a máquina.
- Consultas en vivo: lanzas una consulta desde la consola de Fleet y en segundos tienes la respuesta de miles de equipos a la vez. Es la función que convierte un incidente de «¿está esto en algún sitio más?» en una pregunta de un minuto.
- Recogida de resultados: los logs de las consultas programadas se centralizan y se reenvían al SIEM o al lago de datos (Elastic, Splunk, Snowflake, un bucket S3).
- Inventario y postura: Fleet añade una capa de gestión de vulnerabilidades cruzando el software instalado con feeds de CVE, y comprobaciones de configuración (cifrado de disco, firewall, pantalla de bloqueo).
- Gestión del agente: fleetd empaqueta osquery más un actualizador (Orbit) para desplegar y mantener la versión del agente al día.
Existió un proyecto muy usado llamado Kolide Fleet y una herramienta de solo lectura, Doorman; hoy el desarrollo activo está en Fleet. Para laboratorio, un único contenedor de Fleet con su base de datos basta para enrolar varias máquinas virtuales y practicar.
Packs: consultas empaquetadas y compartidas
Un pack es un grupo de consultas con su intervalo y su plataforma, en un fichero JSON reutilizable. El repositorio de osquery incluye packs de ejemplo (incident-response, hardware-monitoring, vuln-management, osx-attacks). Se toman como base y se recortan: muchos traen consultas caras para una flota grande.
6. Consultas que aportan valor
El catálogo de consultas útiles es enorme; esta tabla recoge un punto de partida repartido entre inventario (responder preguntas de gestión) y detección (encontrar lo anómalo).
| Objetivo | Idea de la consulta | Tabla(s) |
|---|---|---|
| Inventario de software para CVE | Todo el software instalado con su versión, por host | programs, deb_packages, rpm_packages, homebrew_packages, python_packages |
| Equipos sin cifrado de disco | Estado de BitLocker / FileVault / LUKS | bitlocker_info, disk_encryption |
| Cuentas locales nuevas o con UID 0 | Usuarios fuera de la línea base; segundos root | users, user_groups |
| Procesos sin binario en disco | on_disk = 0: binario borrado tras arrancar | processes |
| Listeners inesperados | Puertos a la escucha en interfaces no locales que no estén en la lista aprobada | listening_ports + processes |
| Persistencia | Items de arranque, tareas, servicios y crons que cambian entre snapshots | startup_items, scheduled_tasks, services, crontab, launchd |
| Binarios con ruta o firma sospechosa | Procesos ejecutándose desde temp, con firma inválida (Win/mac) | processes, authenticode, signature |
| Extensiones de navegador no aprobadas | Add-ons instalados por usuario contra una allowlist | chrome_extensions, firefox_addons, safari_extensions |
| Módulos de kernel cargados | LKM fuera de la línea base (Linux) | kernel_modules |
| Integridad de ficheros clave | Hash de sudoers, authorized_keys, hosts, tareas de sistema | hash, file |
El patrón habitual para detección es comparar contra una línea base: se programa la consulta en modo differential y se alerta cuando aparece una fila `added` que no está en la lista de lo conocido. Ese trabajo de «lo nuevo respecto a ayer» se hace en el SIEM, no en osquery.
-- Segundos usuarios con privilegios de root (uid 0) en Linux/macOS SELECT uid, username, description FROM users WHERE uid = 0 AND username != 'root'; -- Software instalado, formato normalizado para cruzar con un feed de CVE SELECT name, version, 'deb' AS type FROM deb_packages UNION SELECT name, version, 'python' AS type FROM python_packages; -- Claves SSH autorizadas por usuario (revisión de accesos) SELECT u.username, k.key_file, k.algorithm, k.key_type FROM users u CROSS JOIN authorized_keys k USING (uid);
7. Rendimiento y el watchdog
Una consulta mal escrita puede castigar un equipo: `SELECT * FROM file` sin un `WHERE path LIKE` intenta recorrer el disco entero, y tablas como `hash` o `certificates` son caras. osquery incluye un watchdog que vigila su propio consumo: si el proceso worker supera los umbrales de CPU o memoria durante varios intervalos, lo mata y lo reinicia, y marca la consulta culpable como *denylisted* durante un tiempo.
| Opción | Qué controla | Nota |
|---|---|---|
| watchdog_memory_limit | Memoria máxima del worker (MB) antes de reiniciarlo | Por defecto ~200 MB; subirlo con criterio en servidores |
| watchdog_utilization_limit | Porcentaje de CPU sostenido tolerado | Un pico puntual no dispara; el uso sostenido sí |
| schedule_splay_percent | Reparte en el tiempo el arranque de las consultas de todos los hosts | Evita que 10.000 equipos ejecuten la misma consulta en el mismo segundo |
| disable_events | Activa o desactiva todo el subsistema de eventos | false para usar process_events / file_events |
| events_expiry | Cuánto tiempo se guardan los eventos en el almacén interno | Ajustar al intervalo de la consulta que los lee |
Prueba cada consulta antes de programarla en la flota
En osqueryi, antepón `.timer on` y mide. Una consulta que tarda 4 segundos en tu portátil puede tardar 40 en un servidor de ficheros con millones de inodos. Multiplica por el tamaño de la flota antes de bajar el intervalo.
8. Lo que osquery no es
Entender los límites evita construir una estrategia de detección sobre una base equivocada.
- No es un EDR. No bloquea procesos, no aísla el host de la red, no pone ficheros en cuarentena y no tiene consola de respuesta. Solo observa y responde preguntas.
- No previene la manipulación de sí mismo. Un atacante con privilegios de administrador puede parar osqueryd, editar su configuración o filtrar sus resultados. La parada del agente debe ser en sí misma una alerta en el SIEM.
- Sin eventos, es una foto puntual. El modo de consulta programada no ve lo que ocurre entre ejecuciones. Para actividad efímera hacen falta las tablas de eventos, con su coste y su dependencia del subsistema de auditoría del SO.
- No detecta por sí solo. osquery entrega datos; la lógica de «esto es anómalo» vive en el SIEM o en las reglas de Fleet. Sin ese destino y sin líneas base, es un inventario que se consulta a mano.
- La cobertura varía por plataforma. Muchas tablas de eventos son solo Linux/macOS; en Windows conviene combinarlo con Sysmon y los canales de eventos nativos.
Dónde encaja osquery
Piensa en osquery como la capa de visibilidad e inventario multiplataforma: inmejorable para responder «¿qué tengo y dónde?» en segundos y para alimentar de contexto al SIEM y a la gestión de vulnerabilidades. La prevención y la respuesta las ponen el EDR, el hardening y los controles de aplicación; la detección de comportamiento la refuerzan Sysmon, auditd o Falco.
Marco legal y ámbito de uso
osquery recopila datos que identifican actividad de personas: procesos que ejecuta cada usuario, sesiones, software instalado, extensiones de navegador, claves de acceso. Desplegarlo sobre sistemas corporativos exige respetar la normativa de protección de datos y laboral: información previa y por escrito a la plantilla sobre qué se recoge y con qué finalidad, proporcionalidad, minimización de datos y plazos de conservación (RGPD y LOPDGDD, y el art. 20.3 del Estatuto de los Trabajadores en cuanto al control empresarial). El acceso o la interceptación no autorizados de sistemas y datos ajenos están tipificados en los arts. 197 bis, 197 ter y 264 del Código Penal. Todo lo de este artículo se aplica a sistemas propios o a una organización que te ha autorizado por escrito a monitorizarlos; las pruebas se hacen en un laboratorio aislado.
Conclusión
osquery resuelve un problema muy concreto y lo resuelve bien: dar visibilidad uniforme de un parque heterogéneo con una sola herramienta y un lenguaje que casi todo el mundo del sector ya conoce. El modelo del sistema operativo como tablas SQL hace que preguntas que antes eran un proyecto —inventario de una librería vulnerable, listeners no aprobados, cuentas con UID 0, persistencia nueva— se conviertan en una consulta que corre igual en Windows, Linux y macOS.
Para sacarle partido en serio hacen falta tres piezas: un plano de control como Fleet para operar la flota y lanzar consultas en vivo, las tablas de eventos activadas donde necesites ver lo que pasa entre consultas, y un SIEM con líneas base donde vivan las alertas. Y tener claro el perímetro: osquery ve y cuenta; no bloquea ni responde. Esa parte es de otras herramientas.
Referencias y recursos
osquery.io — documentación oficial, y osquery.io/schema para el esquema completo filtrable por SO · github.com/osquery/osquery — código, packs de ejemplo (incident-response, vuln-management, osx-attacks) · fleetdm.com y github.com/fleetdm/fleet — plano de control open source para la flota · «osquery Across the Enterprise» y las guías de Palantir/Trail of Bits sobre despliegue y consultas de detección · Nuestros artículos sobre cómo funciona un EDR, threat hunting, Sysmon, auditd y montar un SIEM con Wazuh — el contexto donde encaja osquery
unfantasmaenelsistema.com | Seguridad, sistemas y todo lo que no debería funcionar (pero funciona)

