// OPERACIÓN: Gravity SOC - Mi Centro de Operaciones de Seguridad Distribuido
// Construyendo un Mini-SOC Doméstico con Raspberry Pi y Go
0x00 — EL NACIMIENTO DE GRAVITY SOC
Gravity SOC es mi Centro de Operaciones de Seguridad (SOC) distribuido, ligero y asimétrico.
Nace de mi inquietud y del espíritu de combinar la agilidad de los entornos de placas reducidas (Raspberry Pi) con la supervisión de hardware nativo de Microsoft Windows en un híbrido capaz de detectar atacantes en tiempo real mediante telemetría pura.
El proyecto correlaciona tráfico de red (DNS) y monitorización profunda del sistema (Sysmon) en una arquitectura cliente-servidor de dos capas diseñada bajo la premisa del mínimo consumo y el paso de variables ultra-rápido en memoria, es humilde si, pero potente.
CONTEXTO OPERATIVO
Desarrolladores: Sammi y Antigravity (Gemini y Opus)
Lenguaje: Go (Golang) >= 1.22
Hardware: Raspberry Pi Zero 2 W (Sensor Red), Raspberry Pi 5 (Servidor), PC Windows 11 (Endpoint)
Stack: SQLite 3 (WAL Mode), Sysmon, ETW, Unbound DNS, GoFPDF
Objetivo: Detección de amenazas en tiempo real mediante correlación multi-capa
0x01 — ARQUITECTURA GENERAL
Gravity SOC opera basado en un esquema cliente-servidor de L2/L1, huyendo de la compilación cruzada dependiente de lenguajes como C (CGO).
Se compone de dos módulos principales:
Capa L1 - Los Sensores (Agentes)
El agente de Gravity SOC es un ejecutable polimórfico escrito en Go que se adapta silenciosamente al sistema operativo en el que se despliega.
| Sensor | Plataforma | Función | Tecnología |
|---|---|---|---|
| Host L1 (Windows) | Windows 11 / Endpoint | Supervisión profunda del sistema operativo | wevtutil, ETW, Sysmon |
| Network L1 (Linux) | Raspberry Pi Zero 2 W | Centinela silencioso de red - Interceptor DNS | Unbound DNS, Tailer.go |
Windows (Host L1)
Se engancha limpiamente al registro de Windows y saca toda la lógica compleja de interconectarse a los registros ETW (Event Tracing for Windows).
Aprovechando wevtutil, el agente lee de forma cíclica e inversa los eventos generados por Sysmon, esquivando binarios incompatibles en el runtime de Go.
Eventos capturados:
| EventID | Tipo | Propósito en Detección |
|---|---|---|
| EventID: 1 | Process Create | Creación de procesos y comandos - Detectar ejecución de malware |
| EventID: 3 | Network Connection | Conexiones de red internas y a dominios exteriores - Detectar C2 |
| EventID: 8 | CreateRemoteThread | Inyecciones de memoria remotas - Detectar code injection |
| Adicional | File/Registry/DNS | Lecturas sobre archivos de gran peso / Registro de DNS del host |
Linux (Network L1)
Desplegado en una Raspberry Pi Zero 2 W, desempeña el papel de centinela silencioso dentro de la red corporativa/casera.
El agente intercepta logs volátiles de un servidor DNS local (como Unbound) que expone las resoluciones.
ESCENARIO DE DETECCIÓN
Si un dispositivo intenta buscar malicious.com (ya esté camuflado, ya sea una ráfaga o una botnet) mi agente captura el paquete instantáneamente apoyado por su lectura asíncrona robusta.
Envío Resiliente - El Bus de Eventos
Ambos agentes emplean un bus de eventos (Memory Channel), limitando la huella RAM a no más de 1000 eventos retenidos en simultáneo.
- Envío: Un emisor en forma de bucle enviará mediante peticiones
POSTcifradas todos los eventos - Reintentos Exponenciales: Automáticos de hasta 1 minuto para prevenir congelación o caída general del servidor (L2)
- Arquitectura Cero-Bloqueos: Si el bus se llena, descarta eventos sobrantes para jamás comprometer el estado funcional de la máquina anfitriona
Capa L2 - El Servidor
Desplegado típicamente en un sistema algo mayor (como una Raspberry Pi 5), el "Cerebro" ingiere la telemetría continua de todos los L1 de la red.
| Componente | Tecnología | Función |
|---|---|---|
| Motor SQLite | PRAGMA WAL, Synchronous = NORMAL | Récord histórico en BD de disco local - Tolera flujos violentos de escritura con locks mínimos |
| Correlación Real en Segundos | Consultas SQL cruzadas en tiempo real | Empareja piezas aisladas - dns_alert + network_dns (delta máximo ~10 segundos) |
| Generador de Reportes PDF | GoFPDF | Genera y renderiza de forma autónoma informes ejecutivos diarios en /reports/ |
0x02 — BUGS: HISTORIAL DE CRISIS Y EVOLUCIÓN TECNOLÓGICA
Durante la fase intensiva de despliegue real en ecosistemas Windows y pruebas cruzadas, tuve problemas críticos en el manejo y fiabilidad del agente, diagnosticados por OPUS, y esto era debido a la naturaleza brutal de la API de Windows, lo que forzó diversas iteraciones de diseño.
Bug #1: El Asesino del UTF-16 (Sysmon Windows XML)
Mi Dolor de Cabeza
Los shells y el Event Log API nativa de Windows soltaban ocasionalmente basura little-endian a 16-bits (o nulos 0x00 inyectados).
LA SOLUCIÓN
El agente integró uno de los handlers más limpios y destructivos del entorno: Filtro de Aniquilación de Lista Blanca que destripa radicalmente y reconstruye todo bytes en un UTF-8 validado matemáticamente.
Bug #2: Crash de Conexión de Capa 1 y Freeze Local
EL PROBLEMA
Descubrí caídas completas del Agente al ser incapaz de contactar al servidor, llenando el bus de memoria e imposibilitando las lecturas a wevtutil.
LA SOLUCIÓN
El agente fue mutado y todos los procesos (el capturador, el comprobador sysmon, etc) se modificaron al estándar "cero-bloqueos" de Go (select/default), reventando o ignorando eventos sobrantes para jamás comprometer el estado funcional de la máquina anfitriona.
Bug #3: Ghost Hostnames (Filtración de la Interfaz)
EL PROBLEMA
Variables y marcadores en crudo (os.Open con memory leaks) obligaron a abstraer el cálculo del agente AgentID mediante cacheado persistente antes del Runtime, salvando file handles.
LA SOLUCIÓN
Se aplicó el uso guardado en memoria disco con un pseudo-caché (.gravity-checkpoint) para sobrevivir a los reinicios de Windows sin re-lanzar un aluvión de alertas viejas.
Una especie de cola de eventos contenida en paquetes gracias a ese "cache".
Bug #4: Resiliencia SQL (Cerebro Ciego)
EL PROBLEMA
Al realizar la comparativa SQL para cruzar los eventos en la mesa de correlación (Agente Network VS Agente Windows), database/sql de Go sufría silenciosas paradas cardíacas debido a celdas SQLite desiertas (NULL).
LA SOLUCIÓN
Empleando TrimSpace, COALESCE en inyección pura por SQL, relax de las métricas zonales y variables independientes por agente.
Implementación de LOWER(domain), TRIM() y la función SUBSTR para normalizar los timestamps a nivel de segundo.
0x03 — STACK Y DEPENDENCIAS
| Categoría | Tecnología | Versión / Detalle |
|---|---|---|
| Lenguaje | Go (Golang) | Go >= 1.22 - Agilidad, concurrencia, bajo consumo |
| Base de Datos | SQLite 3 | Modo WAL (Write-Ahead Logging) - Lecturas/escrituras concurrentes |
| API | REST API | Endpoint: /api/v1/events - Recepción de eventos POST cifrados |
| Reporting | GoFPDF | Generación de informes PDF ejecutivos diarios |
| Telemetría Windows | Sysinternals Sysmon | v15 o superior - ETW (Event Tracing for Windows) |
| DNS Monitoring | Unbound DNS | Log tailer asíncrono - Detección de IoC en tiempo real |
| Librerías Go | BIU, tail | XML processing, Linux logging |
| Sistemas Operativos | Windows 11, Parrot OS, Raspberry Pi OS | Ecosistema híbrido multi-plataforma |
0x04 — DIAGRAMA RÁPIDO DEL FLUJO OPERATIVO
Secuencia completa de detección de amenaza distribuida en tiempo real:
Paso 1: Pi Zero 2w (Tailer.go) - Detección en Red
// Sensor de Red L1 - Raspberry Pi Zero 2 W
- Lee silenciosamente fichero de log Unbound
- Encuentra solicitud DNS: botnet-server.ru
- Regex crítico detectado → Empaqueta a
dns_alert - POST HTTP cifrado → Servidor L2 (Pi 5)
Paso 2: Windows 11 (Sysmon_windows.go) - Telemetría de Host
// Sensor de Host L1 - Windows 11 Endpoint
- Bucle de
wevtutilextrae EventID 3 (Network Connection) - Microsoft Edge solicitó DNS: botnet-server.ru
- Proceso originó hilo → Filtra, destruye impurezas UTF-16
- Empaqueta a
network_dns - POST HTTP cifrado → Servidor L2 (Pi 5)
Paso 3: Servidor L2 (Pi 5) - Correlación y Confirmación
// Cerebro Correlador L2 - Raspberry Pi 5
- Motor de correlación expira ventana SQL (ABS <= 10 seg)
- Empareja dominio: botnet-server.ru
Match encontrado:
- dns_alert (Pi Zero) + network_dns (Windows)
- source_ip: 192.168.1.130
- process: msedge.exe
Confirma brecha → Genera informe limpio PDF
0x05 — PASOS DE DESPLIEGUE Y EJECUCIÓN
Requisitos previos:
- Go >= 1.22 instalado
- Acceso a administrador para enganchar a disco y redes
- Microsoft Sysmon correctamente configurado (si testeas agente de host en Windows)
wevtutilfuncional
Compilar y Arrancar el Agente
Entrar a la carpeta del Agente:
cd gravity-soc-agent
Descargar módulos necesarios:
go mod tidy
1. COMPILAR LINUX (Sensor Pi):
# PowerShell (Windows):
$env:GOOS="linux"; $env:GOARCH="arm" # (o "arm64" dependiendo de kernel)
go build -o gravity-agent-linux
2. COMPILAR WINDOWS (Endpoint):
$env:GOOS="windows"; $env:GOARCH="amd64"
go build -o gravity-agent.exe
Ejecutar Agent Win (En Powershell/CMD de Admin):
.\gravity-agent.exe
Compilar y Arrancar el Servidor L2
Entrar a la carpeta Server:
cd gravity-soc-server
go mod tidy
go build -o gravity-server.exe
Ejecución simple (aquí se arranca WebServer):
.\gravity-server.exe
# Recibirá POSTS en /api/v1/events
# Escuchará en puerto 8443
0x06 — MANUAL DE USUARIO
Paso A: Preparar el Cerebro (Pi 5)
- Copiar la carpeta
gravity-soc-server - Compilar el servidor:
go build -o gravity-server main.go - Ejecutar:
./gravity-server - El servidor escuchará en el puerto
8443
Paso B: Preparar el Ojo de Red (Pi 2W)
- Asegúrate de tener instalado Unbound o un simulador de logs
- Ejecuta el agente:
./gravity-agent-linux - El agente comenzará a monitorizar el archivo de log de Unbound en modo tail
Paso C: Preparar el Host (Windows)
- Instala Sysmon (v15 o superior)
- Ejecuta
tmp_agent.execomo Administrador - Verás en consola:
[+] Evento enviado a L2
Cómo Ver los Resultados
Para generar el reporte del día, abre tu navegador en cualquier equipo de la red y entra en:
http://[IP_DE_TU_PI_5]:8443/api/v1/reports/daily
0x07 — PRUEBAS DE FUNCIONAMIENTO (MOCKING)
Para probar que el sistema funciona sin esperar a un ataque real, puedes simular una amenaza:
Simulación en Pi Zero 2w (DNS Alert)
# Añade una línea al log de Unbound:
echo "DNS_ALERT 192.168.1.50 malware-test.com A" >> unbound.log
Simulación en Windows (Network DNS)
# En PowerShell (Windows):
Resolve-DnsName malware-test.com
Verificación de Correlación
Descarga el reporte y verás la Amenaza Confirmada:
| Campo | Valor Esperado |
|---|---|
| Dominio | malware-test.com |
| Source IP | 192.168.1.50 (tu PC Windows) |
| Proceso | powershell.exe |
| Timestamp Delta | < 10 segundos |
| Estado | AMENAZA CONFIRMADA |
0x08 — ARQUITECTURA DE CORRELACIÓN
El motor de correlación es el corazón de mi Gravity SOC.
Opera mediante una ventana deslizante de 10 segundos que empareja eventos aislados.
Algoritmo de Emparejamiento
-- Consulta SQL de Correlación (Pseudocódigo)
SELECT
dns_alert.domain,
dns_alert.source_ip,
network_dns.process_name,
dns_alert.timestamp AS network_time,
network_dns.timestamp AS host_time,
ABS(SUBSTR(dns_alert.timestamp, 1, 19) - SUBSTR(network_dns.timestamp, 1, 19)) AS delta
FROM dns_alert
JOIN network_dns
ON LOWER(TRIM(dns_alert.domain)) = LOWER(TRIM(network_dns.domain))
WHERE
ABS(SUBSTR(dns_alert.timestamp, 1, 19) - SUBSTR(network_dns.timestamp, 1, 19)) <= 10
AND dns_alert.domain IS NOT NULL
AND network_dns.domain IS NOT NULL;
Técnicas de Normalización Implementadas
| Técnica | Función SQL | Propósito |
|---|---|---|
| Normalización de Dominio | LOWER(domain) | Dominios a veces vienen con mayúsculas - Convertir a minúsculas |
| Limpieza de Espacios | TRIM() | Eliminar espacios en blanco al inicio y final |
| Normalización Temporal | SUBSTR(timestamp, 1, 19) | Timestamps a nivel de segundo (eliminar milisegundos que SQLite no comparaba bien) |
| Manejo de Nulos | COALESCE | Subsanar silenciosas paradas cardíacas debido a celdas SQLite desiertas (NULL) |
0x09 — VENTAJAS COMPETITIVAS DE GRAVITY SOC
| Característica | Implementación | Beneficio |
|---|---|---|
| Ligero | Go + SQLite + Raspberry Pi | Consumo mínimo de recursos - No requiere servidores dedicados |
| Asimétrico | Sensores especializados (Red vs Host) | Detección multi-vector - Correlación de eventos de diferentes fuentes |
| Distribuido | Arquitectura L1 (Sensores) / L2 (Cerebro) | Escalabilidad - Añade más sensores sin saturar el servidor |
| Resiliente | Reintentos exponenciales + Checkpoints + Cero-bloqueos | Alta disponibilidad - Sobrevive a caídas de red y reinicios |
| Tiempo Real | Correlación en ventana de 10 segundos | Detección inmediata - No espera a batch processing |
| Económico | Hardware de bajo coste (Raspberry Pi) | Accesible para hogar/pequeña empresa - SOC por < 150€ |
| Open Source | Go (código abierto) + SQLite + Sysmon | Transparencia total - Auditable y personalizable |
0x0A — CASOS DE USO Y ESCENARIOS DE DETECCIÓN
Escenario 1: Detección de Command & Control (C2)
ATAQUE
Un malware se ejecuta en el endpoint Windows y establece comunicación con un servidor C2 mediante DNS Tunneling.
GRAVITY SOC TE PILLA
- Pi Zero: Detecta petición DNS a dominio sospechoso (
c2-evil-domain.ru) - Windows Agent: Captura EventID 3 (Network Connection) del proceso malware (
malware.exe) - Servidor L2: Correlaciona ambos eventos en < 10 segundos
- Alerta: PDF diario muestra: IP infectada, proceso exacto, timestamp
Escenario 2: Detección de movimiento lateral
ATAQUE
Atacante utiliza PsExec para moverse lateralmente en la red y ejecutar comandos en otros equipos.
GRAVITY SOC ROADMAP
- Windows Agent: Captura EventID 1 (Process Create) de
psexec.exe - Windows Agent: Captura EventID 8 (CreateRemoteThread) - Inyección de memoria
- Pi Zero: Detecta múltiples peticiones DNS a IPs internas en corto período
- Servidor L2: Correlaciona el patrón temporal y espacial
- Alerta: Actividad sospechosa de movimiento lateral detectada
Escenario 3: Detección de Data Exfiltration
ATAQUE
Un insider malicioso intenta exfiltrar datos a través de un servicio cloud no autorizado.
GRAVITY SOC ROADMAP II
- Pi Zero: Detecta resolución DNS a servicio cloud no corporativo (
exfil-service.com) - Windows Agent: Captura EventID 3 con conexión de red de larga duración
- Windows Agent: Registra lectura de archivos de gran peso (EventID adicional)
- Servidor L2: Correlaciona: DNS no autorizado + conexión persistente + lectura de archivos
- Alerta: Posible exfiltración de datos detectada
0x0B — CONCLUSIONES
Gravity SOC demuestra que es posible construir un Centro de Operaciones de Seguridad funcional sin depender de soluciones comerciales costosas, eso sí... humilde y puro CLI sin interfaces, lo importante es entender como funciona la correlación de datos entre sistemas a nivel domestico claro.
La combinación de:
- Hardware económico (Raspberry Pi Zero 2 W + Raspberry Pi 5)
- Software eficiente (Go, SQLite)
- Herramientas nativas (Sysmon, ETW, Unbound)
- Arquitectura distribuida (L1 Sensores / L2 Cerebro)
¿Qué logramos?
- Superación del "Asesino del UTF-16" con filtro de aniquilación de lista blanca
- Arquitectura cero-bloqueos en Go (select/default) para estabilidad total
- Sistema de checkpoints para persistencia sin alertas duplicadas
- Motor de correlación SQL con ventana temporal de 10 segundos
- Normalización de datos con COALESCE, LOWER, TRIM, SUBSTR
- Generación automática de reportes PDF ejecutivos diarios
- Consumo mínimo de recursos (< 1000 eventos en RAM)
- Aprender por el camino como siempre
Mi proyecto Gravity SOC es una PoC de que la seguridad avanzada está al alcance de cualquier entorno: desde el hogar hasta la pequeña empresa.
La telemetría pura, la correlación inteligente y la resiliencia arquitectónica son los pilares que sostienen este mini-SOC doméstico.
El futuro de la detección de amenazas no está en las soluciones mastodónticas comerciales, al menos para un ámbito domestico.
Para mi está en sistemas ligeros, distribuidos, económicos y completamente transparentes.
Gravity SOC es el primer paso hacia ese futuro de algo mas ambicioso más adelante, eso si, cuando mi trabajo y obligaciones familiares me lo permitan.
[EOF]
"Gravity SOC defies binary gravity"