
El problema
Un atacante ha comprometido tu red. Se ha movido lateralmente entre servidores Windows, máquinas Linux e infraestructura cloud. La evidencia está dispersa: EVTX de 50 máquinas, logs de auth de una docena de servidores Linux, datos de red de tu EDR. Necesitas reconstruir el camino del atacante — cada salto, cada credencial, cada intento fallido — y lo necesitas ya.
Masstin parsea todas estas fuentes y las fusiona en una única timeline cronológica donde un logon RDP de Windows, un brute-force SSH de Linux y una conexión de red del EDR aparecen lado a lado, en el mismo formato, listos para análisis o visualización en grafos.
- Repositorio: github.com/jupyterj0nes/masstin
- Licencia: AGPL-3.0
- Plataformas: Windows, Linux y macOS — sin dependencias, binario único
Características clave
| Característica | Descripción | Artículo |
|---|---|---|
| Parsing unificado cross-OS | Un solo comando parse-image auto-detecta el SO por partición — NTFS recibe parsing Windows (EVTX + UAL + VSS), ext4 recibe parsing Linux (auth.log, wtmp, audit.log, logs binarios de systemd-journald, etc.) — todo fusionado en una timeline. Apunta a una carpeta con imágenes mixtas y obtén un único CSV. Cero pasos manuales. |
Imágenes forenses |
| graph-hunt: detección estadística | Cada conexión posterior al corte se mide contra la propia línea base de la red: p-valores, la tasa de falsos descubrimientos como único parámetro, clases de Hopper, reconstrucción de la cadena desde una semilla, informe para el analista. Corre directamente desde el CSV, sin base de datos ni plugins | graph-hunt |
| Análisis multi-directorio | Analiza docenas de máquinas a la vez con múltiples flags -d, crítico para investigaciones de ransomware |
Parsear evidencia |
| Timeline multiplataforma | Windows EVTX + Linux SSH + datos EDR en una timeline — parse-image auto-fusiona entre sistemas operativos |
Windows / Linux / Cortex |
| 33+ Event IDs de 12 fuentes EVTX + Scheduled Tasks XML | Security.evtx, Terminal Services, SMBServer, SMBClient, RdpCoreTS, WinRM, WMI-Activity, Sysmon (Event 3, conexiones de red) + detección de tareas remotas — cubriendo RDP, SMB, Kerberos, NTLM, acceso a shares, PowerShell Remoting, WMI y Scheduled Tasks | Security.evtx / RDP / SMB |
| Clasificación de eventos | Cada evento clasificado como SUCCESSFUL_LOGON, FAILED_LOGON, LOGOFF o CONNECT |
Formato CSV — event_type |
| Descompresión recursiva | Extrae automáticamente paquetes ZIP/triage de forma recursiva (KAPE, Velociraptor, UAC, Cortex; tar / tar.gz en streaming, anidados entre sí), gestiona logs archivados con nombres duplicados, detecta contraseñas forenses comunes | Artefactos Linux — soporte triage |
| Linux: inferencia inteligente | Auto-detecta hostname, infiere año desde dpkg.log, soporta Debian (auth.log) y RHEL (secure), formatos RFC3164 y RFC5424 |
Artefactos Linux — inferencia |
| Logs binarios de systemd-journald | Lector en Rust puro para /var/log/journal/*.journal[~] — modo compacto + descompresión zstd. Esencial en Ubuntu 22 / RHEL 8+ con SSSD + Active Directory, donde /var/log/auth.log está vacío porque PAM enruta la autenticación a través del journal. Recorre eventos sshd y aplica las mismas regex Accepted/Failed password que los logs de texto. Funciona en workstations DFIR con Windows sin libsystemd. |
Artefactos Linux — systemd-journald |
| Visualización en grafos con reducción de ruido | Carga directa a Neo4j o Memgraph con agrupación de conexiones (fecha más temprana + recuento) y resolución automática IP-a-hostname | Neo4j / Memgraph |
| Reconstrucción de camino temporal | Query Cypher para encontrar la ruta cronológicamente coherente del atacante entre dos nodos | Neo4j — camino temporal / Memgraph — camino temporal |
| Correlación de sesiones | Campo logon_id permite vincular eventos de logon/logoff para determinar duración de sesión |
Formato CSV — logon_id |
| Modo silencioso | Flag --silent suprime toda la salida para integración con Velociraptor, plataformas SOAR y pipelines de automatización |
Tabla de acciones |
| Procesamiento masivo de evidencia | Apunta -d a una carpeta de evidencia — masstin encuentra recursivamente todas las imágenes E01/VMDK/dd, auto-detecta el SO por partición, extrae todos los artefactos del live + VSS, agrupación de artefactos por imagen en el resumen. Un solo comando para un incidente completo |
Imágenes forenses |
| Detección de BitLocker | Detecta particiones cifradas con BitLocker (firma -FVE-FS-) y avisa al analista — sin perder tiempo en datos ilegibles |
Imágenes forenses |
| VMDK streamOptimized | Soporte completo para VMDKs comprimidos (exportaciones OVA, plantillas cloud). También maneja subidas SFTP incompletas (fallback .filepart) |
Imágenes forenses |
| Recuperación de snapshots VSS | Detecta y extrae EVTX de Volume Shadow Copies — recupera logs borrados por atacantes | Recuperación VSS |
| Soporte de volúmenes montados | Apunta -d D: a un volumen montado o usa --all-volumes — EVTX live + recuperación VSS desde discos conectados, sin necesidad de crear imagen |
Imágenes forenses |
| Parsing UAL | Detecta automáticamente bases de datos UAL (User Access Logging) — 3 años de historial de acceso a servidor que sobreviven al borrado de logs | UAL |
| MountPoints2 del registro | Extrae NTUSER.DAT de cada perfil de usuario y parsea MountPoints2 — revela conexiones usuario→servidor share con timestamps, sobrevive al borrado de logs. Soporte de hives sucios + transaction logs | MountPoints2 |
| EVTX carving | carve-image escanea el disco raw buscando chunks EVTX en espacio no asignado — recupera eventos después de que los logs Y los VSS hayan sido borrados. Implementa Nivel 1 (chunks completos de 64 KB) + Nivel 2 (detección de records huérfanos); el Nivel 3 (template matching) está planificado. Construye EVTX sintéticos agrupados por provider y los parsea por el pipeline completo. Tres bugs del parser upstream (bucles infinitos y OOMs de varios GB sobre BinXML corrupto) fueron reportados y arreglados en evtx 0.11.2; masstin mantiene el aislamiento en threads + catch_unwind + --skip-offsets como red de seguridad belt-and-suspenders |
EVTX carving |
| Reporte transparente | La CLI muestra descubrimiento de artefactos, progreso de procesamiento, inferencias de hostname/año y recuento de eventos por artefacto | Parsear evidencia |
Instalar
Descargar binario pre-compilado (recomendado)
No necesitas Rust. Solo descarga y ejecuta.
| Plataforma | Descarga |
|---|---|
| Windows | masstin-windows.exe |
| Linux | masstin-linux |
| macOS (Apple Silicon) | masstin-macos-arm64 |
| macOS (Intel) | masstin-macos-x86_64 |
Ve a Releases y descarga el binario para tu plataforma. Nada más.
Compilar desde el código fuente (alternativa)
git clone https://github.com/jupyterj0nes/masstin.git
cd masstin && cargo build --release
Parsear evidencia
# Imágenes forenses — auto-detecta Windows y Linux, timeline única
masstin -a parse-image -f DC01.e01 -f ubuntu-server.vmdk -o timeline.csv
# Escanear carpeta de evidencia — cualquier mezcla de imágenes Windows/Linux
masstin -a parse-image -d /evidence/all_machines/ -o full_timeline.csv
# Parsear logs extraídos desde directorios
masstin -a parse-windows -d /evidence/DC01 -d /evidence/SRV-FILE -o windows.csv
masstin -a parse-linux -d /evidence/linux-triage/ -o linux.csv
Visualizar en base de datos de grafos
# Cargar en Memgraph (sin autenticacion)
masstin -a load-memgraph -f full-timeline.csv --database localhost:7687
# Cargar en Neo4j
masstin -a load-neo4j -f full-timeline.csv --database localhost:7687 --user neo4j
Un timeline de masstin en Memgraph Lab: todos los logins de la hora en que entró el atacante, y después una consulta del catálogo devuelve el camino cronológicamente válido desde la IP del atacante hasta la estación. Caso DFIR Madness “Szechuan sauce”.
Reconstruir el camino del atacante
La query de camino temporal encuentra la ruta cronológicamente coherente entre dos nodos:
MATCH path = (start:host {name:'10.10.1.50'})-[*]->(end:host {name:'SRV-BACKUP'})
WHERE ALL(i IN range(0, size(relationships(path))-2)
WHERE localDateTime(relationships(path)[i].time) < localDateTime(relationships(path)[i+1].time))
RETURN path ORDER BY length(path) LIMIT 5

Cazar sin saber qué buscar
Con el timeline hecho, graph-hunt-csv responde a la pregunta que el analista trae el primer día: de todo lo que pasó después del compromiso, ¿qué es nuevo para esta red? Sin base de datos ni plugins: cada conexión de la ventana se mide contra la línea base, el único número que eliges es la tasa de falsos descubrimientos, y el informe explica cada hallazgo en palabras. Sin ninguna pista: en el conjunto público de Los Álamos (21 millones de logins, 749 eventos del equipo rojo etiquetados) la máquina del equipo rojo sale en el puesto 1 y 204 conexiones superan la tasa de falsos descubrimientos del 5 %. Los 22 minutos de ejecución están recortados en la grabación.
masstin -a graph-hunt-csv -f timeline.csv --investigation-from "2026-03-15 00:00:00" \
--report hunt.md -o hunt.csv
Cómo decide, y qué encontró en el conjunto público de LANL, está en el artículo de graph-hunt.
Acciones disponibles
| Acción | Descripción |
|---|---|
parse-windows |
Parsea EVTX de Windows desde directorios o ficheros (soporta triage comprimido) |
parse-linux |
Parsea logs de Linux: auth.log, secure, messages, audit.log, utmp, wtmp, btmp, lastlog |
parser-elastic |
Parsea logs de Winlogbeat en JSON exportados desde Elasticsearch |
parse-cortex |
Consulta la API de Cortex XDR para conexiones de red (RDP/SMB/SSH) |
parse-image |
Auto-detecta el SO por partición. Abre imágenes E01/dd/VMDK (incluido streamOptimized), escanea carpetas de evidencia (-d /evidence/), volúmenes montados (-d D:) o --all-volumes. Detecta BitLocker. NTFS → EVTX + UAL + VSS + Tasks. ext4 → logs Linux. Todo fusionado en un CSV |
parse-massive |
Como parse-image pero también incluye EVTX y logs sueltos de los directorios -d — útil cuando la evidencia es una mezcla de imágenes de disco y paquetes triage extraídos |
carve-image |
Último recurso. Escanea el disco raw buscando chunks EVTX en espacio no asignado. Recupera eventos de movimiento lateral después de que logs + VSS hayan sido borrados. Usa --carve-unalloc para escanear solo espacio no asignado |
parse-cortex-evtx-forensics |
Consulta la API de Cortex XDR para colecciones EVTX forenses de múltiples máquinas |
parse-custom |
Parsea logs de texto o JSON arbitrarios (VPN, firewall, proxy, aplicación web, Mordor / OTRF) usando ficheros YAML de reglas con extractores csv, regex, keyvalue y json. Trae tu propio formato de log — ver parsers personalizados de masstin |
merge |
Combina múltiples CSVs en una única timeline cronológica |
load-neo4j |
Sube la timeline a Neo4j para visualización en grafos |
load-memgraph |
Sube la timeline a Memgraph para visualización en grafos en memoria |
merge-neo4j-nodes |
Fusiona dos nodos :host del grafo después de cargar (por ejemplo, cuando una IP y un hostname no se unificaron automáticamente). No requiere APOC |
merge-memgraph-nodes |
Igual que el anterior, para Memgraph. No requiere MAGE |
graph-hunt-csv |
Caza estadística de movimiento lateral directamente desde el CSV del timeline. Cada conexión posterior a --investigation-from se mide contra la línea base; Benjamini-Hochberg a --alpha decide; --seed reconstruye cadenas, --report escribe el informe para el analista, --sigma une los hits de Hayabusa / Chainsaw. Sin base de datos. Ver post graph-hunt |
graph-hunt |
La misma caza sobre un grafo cargado en Memgraph con --ungrouped. Todo se calcula en memoria; no necesita MAGE |
graph-hunt-neo4j |
La misma caza sobre Neo4j (--db <nombre> para bases con nombre). No necesita el plugin GDS |
parse-windows vs parse-image vs parse-massive — qué procesa cada una
Las tres acciones del lado Windows se diferencian por qué les metes, no por el parser subyacente — el dispatch EVTX es el mismo en todas (routing por Provider.Name, providers desconocidos se saltan silenciosamente).
| Fuente | parse-windows |
parse-image |
parse-massive |
|---|---|---|---|
| Ficheros EVTX sueltos y directorios | ✅ | ❌ | ✅ |
| Recorrido recursivo de ZIP (anidamiento ilimitado) | ✅ | ❌ | ✅ |
Fallback Provider.Name para EVTX archivados / renombrados |
✅ | ✅ | ✅ |
| Imágenes forenses de disco (E01, VMDK, raw, dd, img) | ❌ | ✅ | ✅ |
Walker NTFS → winevt/Logs + recovery VSS |
❌ | ✅ | ✅ |
Bases de datos UAL (LogFiles/Sum/*.mdb) |
❌ | ✅ | ✅ |
Scheduled Tasks XML (System32/Tasks/) |
❌ | ✅ | ✅ |
| MountPoints2 (hive de registro NTUSER.DAT) | ❌ | ✅ | ✅ |
| Triage detection (KAPE / Velociraptor / UAC / Cortex XDR) con labels por fuente | ❌ | ❌ | ✅ |
Promoción de directorios -d como loose artifacts al pipeline |
❌ | ❌ | ✅ |
Regla rápida:
- Carpeta / ZIP / EVTX suelto →
parse-windows - Imagen forense (
.e01,.vmdk,.raw) →parse-image - Evidencia mixta (imagen + zip + triage + ficheros sueltos) →
parse-massive
En las tres, cualquier EVTX cuyo Provider.Name coincida con un canal que masstin conoce se parsea — independientemente del nombre de fichero. Logs archivados (Security-YYYY-MM-DD-HH-MM-SS.evtx producidos por la política de retención “Archive the log when full”), copias renombradas por el operador, y extracciones de herramientas de terceros se enrutan todas correctamente. Ver post de EVTX archivados para la historia completa.
Documentación
Artefactos
| Artefacto | Artículo | |
|---|---|---|
| Security.evtx (14 Event IDs) | Security.evtx y movimiento lateral | |
| Terminal Services EVTX | Terminal Services EVTX | |
| SMB EVTX | Eventos SMB en EVTX | |
| WinRM, WMI-Activity + Scheduled Tasks | PowerShell Remoting (Event 6), WMI remoto (Event 5858) y tareas programadas remotas (campo Author) | WinRM, WMI y Tasks |
| MountPoints2 (NTUSER.DAT) | Conexiones a shares remotos desde el registro — usuario→servidor con timestamps, sobrevive al borrado de logs | MountPoints2 |
| Logs de Linux | Artefactos forenses de Linux | |
| Winlogbeat JSON | Winlogbeat: artefactos en JSON | |
| Cortex XDR | Cortex XDR: artefactos forenses | |
| Parsers personalizados (BYO logs) | VPN, firewall, proxy, aplicación web — define tu propio formato de log con un fichero YAML de reglas y parséalo como cualquier otra fuente. Parsers personalizados de masstin |
Formato de salida y funcionalidades avanzadas
| Tema | Artículo |
|---|---|
| Columnas CSV, event_type, mapeo Event ID, logon_id, detail | Formato CSV y Clasificación de Eventos |
| Análisis de imágenes forenses y recuperación VSS | Recuperando logs borrados desde VSS |
| User Access Logging (UAL) | Historial de acceso a servidor desde bases de datos ESE |
| vshadow-rs — parser VSS en Rust puro | vshadow-rs |
Detección de triages (KAPE / Velociraptor / Cortex) — reconocimiento automático de paquetes triage dentro de parse-image y parse-massive |
Detección de triages en masstin |
| graph-hunt — detección estadística de movimiento lateral: p-valores contra la propia línea base de la red, tasa de falsos descubrimientos, clases de Hopper, cadenas desde semilla, informe para el analista; desde el CSV, Memgraph o Neo4j, sin plugins | graph-hunt en masstin |
Bases de datos graficas
| Base de datos | Artículo |
|---|---|
| Neo4j | Neo4j y Cypher: visualización y queries |
| Memgraph | Memgraph: visualización en memoria |
$ comments