
CLI/TUI de Python para triaje forense de sistemas Ubuntu — detecta y remedia mecanismos de persistencia con recolección de artefactos, correlación de líneas de tiempo e integración con Wazuh.
Triaje forense para sistemas Ubuntu en vivo — recolección automatizada de artefactos, detección de persistencia y remediación guiada en aproximadamente un minuto.
Cuando sospechas que un sistema Linux está comprometido, los primeros 30-40 minutos suelen dedicarse a ejecutar los mismos diez comandos en secuencia: revisar los procesos en ejecución, buscar tareas cron extrañas, hacer grep de LD_PRELOAD, escanear authorized_keys en busca de entradas nuevas, auditar sudoers. Cada paso es manual, implica cambiar de contexto y es propenso a errores bajo presión. Si te saltas una fuente — por ejemplo, /etc/sudoers.d/ en lugar de solo /etc/sudoers, o los crontabs de usuario además de /etc/cron.d/ — tendrás una imagen incompleta.
Las opciones existentes no resuelven esto de forma limpia. lynis es un auditor de endurecimiento, no una herramienta de triaje — informa de debilidades de configuración en un sistema limpio y genera ruido en uno comprometido. chkrootkit y rkhunter buscan firmas de rootkits conocidos, pero son ciegos a técnicas de persistencia novedosas como temporizadores systemd abusados o entradas cron de aspecto legítimo. Las consultas genéricas a un SIEM requieren una infraestructura de logs que puede no existir en el sistema que estás examinando. Y las suites forenses como Volatility se centran en imágenes de memoria, no en una shell en vivo sobre un host en ejecución.
El vacío que queda es una herramienta que se ejecute en el sistema en vivo ahora mismo, cubra los vectores de persistencia más comunes, correlacione la actividad entre fuentes de logs en una línea temporal y te diga exactamente qué revisar — sin requerir un agente externo, una base de datos ni conexión a internet.
ubuntils se ejecuta en cuatro etapas secuenciales:
/proc, tablas cron, unidades systemd, claves SSH, archivos sudoers, definiciones de entorno, integridad de paquetes (dpkg --verify), configuración de PAM/NSS y módulos del kernel cargados. La mayoría de los recolectores terminan en uno o dos segundos; dpkg --verify, que vuelve a comprobar cada archivo de paquete instalado, domina el tiempo — un escaneo completo tardó entre 29 y 68 segundos en una VM de escritorio Ubuntu 26.04 arm64.--rules — sobre los artefactos recolectados, produciendo una lista de hallazgos clasificada y con puntuación de confianza en aproximadamente un segundo.--json).ubuntils en sí no realiza llamadas de red, y todas sus funciones — incluidas las reglas personalizadas y la correlación — se ejecutan contra artefactos recolectados localmente. La única forma en que los hallazgos pueden salir del host es la integración con Wazuh: si hay un agente de Wazuh instalado, un scan en vivo escribe sus hallazgos en un archivo local que el agente envía después a su gestor. Pasa --no-wazuh para desactivarlo durante una ejecución.
ubuntils scan no cambia con nada de lo que sigue — sigue siendo 100% en vivo, de un solo host, y cada flag existente funciona de forma idéntica. Dos comandos adicionales, collect y analyze, dividen el mismo pipeline de detección/línea de tiempo en un flujo de trabajo de adquirir-y-analizar apto para uso offline en casos donde no puedes (o no quieres) ejecutar la detección directamente en el host bajo investigación — consulta Análisis offline: collect y analyze más abajo, incluidos sus matices sobre la cobertura de detección.
Ubuntu 22.04+ y cualquier sistema con PEP 668 (recomendado):
Ubuntu 22.04+ bloquea pip install a nivel de sistema. Usa pipx — gestiona el entorno de forma transparente para que nunca tengas que pensar en ello:
sudo apt install pipx -y
pipx ensurepath # then open a new shell
git clone https://github.com/asmitdesai/ubuntils.git
cd ubuntils
pipx install -e .
ubuntils scan # not `ubuntils scan` — see below
Ejecútalo como tu usuario normal: scan y collect se reinvocan a sí mismos bajo sudo. Escribir ubuntils … tú mismo falla con command not found, porque el secure_path de sudo no incluye ~/.local/bin, donde pipx coloca el comando. Si necesitas iniciarlo desde un shell de root, llama al binario instalado por su ruta (~youruser/.local/bin/ubuntils scan), o instálalo en un entorno virtual en su lugar:
python3 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/ubuntils scan
Sistemas más antiguos / instalación manual:
git clone https://github.com/asmitdesai/ubuntils.git
cd ubuntils
pip install -r requirements.txt -e .
ubuntils scan
ubuntils requiere root para acceder por completo a los artefactos. Si ejecutas ubuntils scan como un usuario no root, se reinvocará automáticamente con sudo usando el mismo intérprete de Python (por ruta absoluta), de modo que se utilice el entorno correcto sin reenviar tu PATH al proceso root. Cada comando externo (ss, dpkg, systemctl, …) se resuelve en una ruta de búsqueda fija propiedad de root, nunca tu PATH. Ejecutarlo sin root omitirá /etc/shadow, algunas entradas de /proc y archivos cron protegidos, y registrará advertencias por cada uno.
Solo detección — TUI interactiva:
ubuntils scan
Detección con salida JSON guardada en archivo:
ubuntils scan --json > /tmp/triage-$(hostname)-$(date +%Y%m%d).json
Detección con vista previa de remediación por CLI (ejecución en seco — sin cambios aplicados):
ubuntils scan --remediate
Detección con remediación de CLI aplicada:
ubuntils scan --remediate --confirm
Versión para imprimir:
ubuntils version
Recopila un paquete a prueba de manipulaciones para su posterior análisis o análisis sin conexión:
ubuntils collect --output /path/to/bundle.tar.gz
Analizar un paquete recopilado previamente (no se requiere root):
ubuntils analyze /path/to/bundle.tar.gz --json
Analizar una imagen forense montada o un árbol de sistema de archivos extraído en lugar de un paquete:
ubuntils analyze --root /mnt/forensic-image --json
Consulta Análisis sin conexión: recopilar y analizar para conocer el formato del paquete y — lo que es más importante — qué no puede detectar el análisis sin conexión en comparación con un scan en vivo.