Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
ubuntils — 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. | Kitploit
Herramientas/GitHubGitHub/asmitdesai/ubuntils
Herramientas DefensivasGestión de Indicadores de Compromiso (IOC)Mecanismos de PersistenciaAnálisis de VulnerabilidadesScripting y AutomatizaciónAuditoría de ConfiguraciónAnálisis ForenseForensia DigitalRespuesta a IncidentesAnálisis de Registros
GitHub
113hace 1 díaAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
asmitdesai/ubuntils

ubuntils

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.

Ver Repositorio
Compartir

ubuntils

Triaje forense para sistemas Ubuntu en vivo — recolección automatizada de artefactos, detección de persistencia y remediación guiada en menos de 5 segundos.

CI Python Tests Coverage License Arch Ubuntu Offline analysis Detection rules SIEM


El problema

Cuando sospechas que un sistema Linux ha sido 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 nuevas entradas, 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 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 con apariencia legítima. 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 orientan a imágenes de memoria, no a una shell en vivo sobre un host en ejecución.

El vacío 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.


Qué hace ubuntils

ubuntils se ejecuta en cuatro etapas secuenciales:

  1. Recolección — Once recolectores reúnen artefactos forenses de forma concurrente desde /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. Tarda aproximadamente 2,5 segundos en un sistema típico.
  2. Detección — Un motor de detección ejecuta las dieciséis reglas integradas — más cualquier regla personalizada cargada con --rules — sobre los artefactos recolectados, produciendo una lista de hallazgos clasificada y con puntuación de confianza en aproximadamente un segundo.
  3. Línea temporal — Un constructor de línea temporal lee syslog, journald y auditd en paralelo y correlaciona los eventos cronológicamente, añadiendo aproximadamente 0,3 segundos. Cada hallazgo se correlaciona automáticamente con la línea temporal, de modo que lleva consigo los eventos cercanos relacionados con él.
  4. Salida — Los resultados aparecen ya sea en una TUI interactiva de cuatro pestañas (por defecto) o como JSON estructurado en stdout (--json).

ubuntils en sí no realiza llamadas de red, y todas las 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 Wazuh instalado, un scan en vivo escribe sus hallazgos en un archivo local que el agente luego envía a su gestor. Pasa --no-wazuh para desactivarlo durante una ejecución.

ubuntils scan no se ve afectado por todo 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 temporal en un flujo de trabajo de adquirir-y-analizar apto para uso offline, para casos en los que 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, incluidas sus advertencias sobre la cobertura de detección.


Instalació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:```bash sudo apt install pipx -y cd ubuntils pipx install -e . ubuntils scan

root@kitploit:~
**Sistemas más antiguos / instalación manual:**```bash
git clone https://github.com/asmitdesai/ubuntils.git
cd ubuntils
pip install -r requirements.txt -e .
ubuntils scan

ubuntils requiere root para acceder completamente 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.


Inicio rápido

Solo detección — TUI interactiva:```bash sudo ubuntils scan

root@kitploit:~
**Detección con salida JSON guardada en archivo:**```bash
sudo ubuntils scan --json > /tmp/triage-$(hostname)-$(date +%Y%m%d).json

Detección con vista previa de remediación mediante CLI (ejecución en seco — sin aplicar cambios):```bash sudo ubuntils scan --remediate

root@kitploit:~
**Detección con remediación de CLI aplicada:**```bash
sudo ubuntils scan --remediate --confirm

Versión para imprimir:```bash ubuntils version

root@kitploit:~
**Recopila un paquete a prueba de manipulaciones para su posterior análisis o análisis sin conexión:**```bash
sudo ubuntils collect --output /path/to/bundle.tar.gz

Analizar un paquete recopilado previamente (no se requiere root):```bash ubuntils analyze /path/to/bundle.tar.gz --json

root@kitploit:~
**Analizar una imagen forense montada o un árbol de sistema de archivos extraído en lugar de un paquete:**```bash
ubuntils analyze --root /mnt/forensic-image --json

Consulta Análisis offline: recopilar y analizar para conocer el formato del paquete y — lo que es más importante — qué no puede detectar el análisis offline en comparación con un scan en vivo.


Flags y configuración```

ubuntils scan [OPTIONS] --json Output JSON to stdout instead of launching the TUI --output FILE Write the JSON report to FILE (implies --json) --remediate Run the remediation engine after detection --confirm Required with --remediate to actually apply changes (else dry-run) --min-confidence N Only auto-remediate findings with confidence >= N (default 40) --no-wazuh Never forward findings to a local Wazuh agent --config FILE YAML allowlist of findings to suppress (see below) --baseline FILE YAML baseline of environment-specific known-good fingerprints to suppress (see below) --since TIME Limit the timeline to events since TIME (e.g. '24h', '7d', '2026-05-20') --rules FILE YAML file of custom detection rules to add (see below) --verbose Verbose structlog output

ubuntils collect [OPTIONS] --output FILE Bundle path to write (default ./ubuntils-bundle-.tar.gz) --verbose Verbose structlog output

ubuntils analyze (BUNDLE | --root PATH) [OPTIONS] --root PATH Analyze a mounted image / artifact tree instead of a bundle --json Output JSON instead of launching the TUI --output FILE Write the JSON report to FILE (implies --json) --config FILE YAML allowlist of findings to suppress (same format as scan) --baseline FILE YAML baseline of environment-specific known-good fingerprints to suppress (same format as scan) --rules FILE YAML file of custom detection rules to add (same format as scan) --since TIME Limit the timeline to events since TIME (e.g. '24h', '7d', '2026-05-20') --verbose Verbose structlog output

ubuntils version Print version string and exit

root@kitploit:~
### Lista blanca de falsos positivos (`--config`)

Un host recién aprovisionado o gestionado por CI genera ruido esperado — claves de despliegue, crontabs de aprovisionamiento, inicialización de shell preconfigurada. En lugar de enseñar a los respondedores a filtrarlo mentalmente, suprimirlo explícitamente con una lista blanca YAML:```yaml
# allowlist.yaml
allowlist:
  rules:
    - SHELL_RC_MODIFICATION          # suppress this rule entirely
  paths:
    - /home/ci/.ssh/authorized_keys  # suppress any finding on this exact path

| -s | --server | SERVER | http://localhost:8080 | URL del servidor de escaneo | | -t | --token | TOKEN | - | Token de autenticación | | -o | --output | FILE | - | Archivo de salida | | -f | --format | FORMAT | json | Formato de salida (json, yaml, csv) | | -v | --verbose | - | false | Habilitar registro detallado | | -q | --quiet | - | false | Modo silencioso | | --timeout | - | SECONDS | 30 | Tiempo de espera de la solicitud | | --retry | - | COUNT | 3 | Número de reintentos | | --insecure | - | - | false | Omitir la verificación del certificado TLS |

Ejemplos

root@kitploit:~
# Escaneo básico
scanner scan --target example.com

# Escaneo con autenticación
scanner scan --target example.com --token $API_TOKEN

# Salida en formato JSON
scanner scan --target example.com --format json --output results.json

# Escaneo con tiempo de espera personalizado
scanner scan --target example.com --timeout 60 --retry 5

Configuración

La herramienta se puede configurar mediante un archivo de configuración o variables de entorno.

Archivo de configuración

Cree un archivo config.yaml en el directorio de trabajo:

root@kitploit:~
server: http://localhost:8080
token: your-api-token
timeout: 30
retry: 3
output:
  format: json
  file: results.json

Variables de entorno

VariableDescripciónValor predeterminado
SCANNER_SERVERURL del servidor de escaneohttp://localhost:8080
SCANNER_TOKENToken de autenticación-
SCANNER_TIMEOUTTiempo de espera de la solicitud30
SCANNER_RETRYNúmero de reintentos3
SCANNER_INSECUREOmitir la verificación del certificado TLSfalse

Integración con CI/CD

GitHub Actions

root@kitploit:~
name: Security Scan
on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run security scan
        run: |
          scanner scan --target example.com --format json --output results.json
      - name: Upload results
        uses: actions/upload-artifact@v3
        with:
          name: scan-results
          path: results.json

GitLab CI

root@kitploit:~
security-scan:
  stage: test
  script:
    - scanner scan --target example.com --format json --output results.json
  artifacts:
    paths:
      - results.json

Solución de problemas

Problemas comunes

Error: No se puede conectar al servidor

Verifique que el servidor de escaneo esté en ejecución y sea accesible:

root@kitploit:~
curl -v http://localhost:8080/health

Error: Token de autenticación no válido

Asegúrese de que el token sea correcto y no haya expirado:

root@kitploit:~
scanner auth verify --token $API_TOKEN

Error: Tiempo de espera de la solicitud agotado

Aumente el valor de tiempo de espera:

root@kitploit:~
scanner scan --target example.com --timeout 120

Registro de depuración

Habilite el registro detallado para solucionar problemas:

root@kitploit:~
scanner scan --target example.com --verbose

Contribución

Las contribuciones son bienvenidas. Por favor, consulte CONTRIBUTING.md para obtener más detalles.

Licencia

Este proyecto está licenciado bajo la Licencia MIT. Consulte el archivo LICENSE para obtener más detalles.```bash sudo ubuntils scan --json --config allowlist.yaml

root@kitploit:~
La supresión siempre es explícita — por id de regla y/o ruta exacta del artefacto. No existe un interruptor general de "ignorar todo". Hay un ejemplo en [`examples/allowlist.yaml`](https://github.com/asmitdesai/ubuntils/blob/main/examples/allowlist.yaml).

### Establecimiento de línea base de elementos conocidos como buenos (`--baseline`)

`--config` suprime una regla o ruta *en todas partes, para cualquiera que ejecute ubuntils contra este código base*. `--baseline` es más acotado y específico del entorno: indica que "en *este* entorno, este artefacto exacto — esta clave SSH, este archivo RC — se sabe que es bueno", sin silenciar la regla o la ruta para todos los demás hosts que escanees con la misma herramienta. Se mantiene como un archivo separado de `--config` por la misma razón por la que `--rules` es independiente: la supresión y la inclusión en lista de permitidos a nivel de regla son preocupaciones distintas que no deberían convivir en un solo archivo.```yaml
# baseline.yaml
baseline:
  - rule_id: SSH_UNAUTHORIZED_KEY
    fingerprint: ci@ci-runner          # substring match against the finding's raw_value
  - rule_id: SHELL_RC_MODIFICATION
    fingerprint: /home/deploy/.bashrc  # exact match against the finding's artifact_path
-h, --helpMuestra el mensaje de ayuda y sale
-v, --versionMuestra la versión del programa y sale
-d, --debugHabilita el registro de depuración
-c, --configRuta al archivo de configuración
-o, --outputRuta del archivo de salida
-f, --formatFormato de salida (json, xml, csv)
-q, --quietModo silencioso, suprime la salida
-V, --verboseModo detallado, aumenta la salida
sudo ubuntils scan --json --baseline baseline.yaml
root@kitploit:~
Una entrada de línea base coincide por `rule_id` más un `fingerprint` probado como una subcadena del `raw_value` del hallazgo o una coincidencia exacta contra su `artifact_path`. Una coincidencia elimina el hallazgo del informe por completo — la supresión nunca es silenciosa, sin embargo: el número de hallazgos que una línea base eliminó siempre es visible en `scan_metadata.suppressed_by_baseline`. La supresión mediante lista de permitidos (`--config`) sigue aplicándose por encima de la supresión de línea base. Funciona de forma idéntica en `scan` y `analyze`. Hay un ejemplo en [`examples/baseline.yaml`](https://github.com/asmitdesai/ubuntils/blob/main/examples/baseline.yaml).

### Reglas de detección personalizadas (`--rules`)

`--config` *suprime* hallazgos; `--rules` los *añade*. Son archivos deliberadamente separados porque son preocupaciones opuestas.

Un archivo de reglas es solo coincidencia de patrones — sin expresiones, sin condicionales y sin ejecución de código, por lo que cargar uno nunca puede ejecutar lógica proporcionada por un atacante. Cada regla nombra un `source` de artefacto, un modo de `match` y un `pattern`:```yaml
# custom_rules.yaml
rules:
  - id: CUSTOM_KNOWN_MINER
    severity: HIGH                     # HIGH | MEDIUM | LOW
    title: Known cryptominer in process cmdline
    description: A running process command line matches a known miner.
    source: process                    # cron | environment | ssh | process | network
    match: substring                   # regex | substring | glob
    pattern: xmrig

| --no-color | Desactiva la salida en color | | --debug | Habilita el registro de depuración | | --verbose | Habilita el registro detallado | | --version | Muestra la versión del programa y sale | | --help | Muestra el mensaje de ayuda y sale |

Ejemplos

root@kitploit:~
# Escanear un objetivo con salida en formato JSON
python3 CVE-Scanner.py -u https://example.com -o json

# Escanear múltiples objetivos desde un archivo con 10 hilos
python3 CVE-Scanner.py -f targets.txt -t 10

# Escanear con un proxy y guardar los resultados en un archivo
python3 CVE-Scanner.py -u https://example.com -p http://127.0.0.1:8080 -o output.txt

Salida

La herramienta genera un informe detallado que incluye:

  • Información del objetivo: URL, dirección IP, puertos abiertos
  • Tecnologías detectadas: Servidores web, frameworks, lenguajes de programación
  • Vulnerabilidades encontradas: CVE ID, descripción, puntuación CVSS, referencias
  • Recomendaciones: Pasos sugeridos para mitigar las vulnerabilidades

Contribuciones

¡Las contribuciones son bienvenidas! Por favor, sigue estos pasos:

  1. Haz un fork del repositorio
  2. Crea una rama para tu funcionalidad (git checkout -b feature/nueva-funcionalidad)
  3. Realiza tus cambios y haz commit (git commit -am 'Añade nueva funcionalidad')
  4. Haz push a la rama (git push origin feature/nueva-funcionalidad)
  5. Abre un Pull Request

Licencia

Este proyecto está licenciado bajo la Licencia MIT - consulta el archivo LICENSE para más detalles.

Descargo de responsabilidad

Esta herramienta está destinada únicamente a fines educativos y de pruebas de seguridad autorizadas. Los autores no se hacen responsables del uso indebido o de los daños causados por esta herramienta. Utilízala únicamente en sistemas que poseas o para los que tengas permiso explícito de probar.

Créditos

  • NVD - National Vulnerability Database
  • CVE - Common Vulnerabilities and Exposures
  • Shodan - Motor de búsqueda para dispositivos conectados a Internet```bash sudo ubuntils scan --json --rules custom_rules.yaml
root@kitploit:~
| `source` | Se compara con |
|---|---|
| `cron` | El comando cron (ruta: el archivo crontab) |
| `environment` | La línea sin procesar de entorno/inicialización del shell (ruta: el archivo que la define) |
| `ssh` | Tipo de clave, datos de la clave y comentario (ruta: el archivo `authorized_keys`) |
| `process` | La línea de comandos del proceso (ruta: la ruta del ejecutable) |
| `network` | La descripción de la conexión (ruta: `remote_addr:remote_port`) |

`regex` y `substring` coinciden con la columna de texto; `glob` coincide con la columna de ruta — por lo que un glob de `network` como `203.0.113.*:*` apunta al endpoint remoto. Los hallazgos de reglas personalizadas son solo de marcado (nunca se remedian automáticamente) y siguen estando sujetos a la supresión de `--config`. Hay un ejemplo en [`examples/custom_rules.yaml`](https://github.com/asmitdesai/ubuntils/blob/main/examples/custom_rules.yaml).

### Integridad del informe

Cada informe `--json` incluye un campo `report_sha256` — un SHA-256 sobre el contenido canónico del informe. Esto hace que un artefacto de triaje recopilado sea a prueba de manipulación y te permite referenciar un escaneo específico por su digest en un expediente. El informe también registra `tool_version`, `hostname` y una marca de tiempo UTC `generated_at` bajo `scan_metadata`. Para `scan`, `hostname`/`ubuntu_version` describen la máquina en la que se está ejecutando `ubuntils`; para `analyze --root` se leen del propio `/etc/hostname` y `/etc/os-release` de la imagen. Para `analyze BUNDLE`, en cambio, provienen del propio manifiesto del bundle — el host que fue *recopilado*, no el host que ejecuta `analyze` — junto con `collection_run_id` y los `collected_at_utc_start`/`collected_at_utc_end` de la recopilación, de modo que el registro de cadena de custodia del informe sigue a la evidencia en lugar de a la estación de trabajo del analista.

**Verificar un informe.** El informe se emite en forma canónica (claves ordenadas, sangría de 2 espacios), y el digest cubre todo excepto el propio `report_sha256`:```python
import hashlib, json
doc = json.load(open("report.json"))
claimed = doc.pop("report_sha256")
assert hashlib.sha256(json.dumps(doc, indent=2, sort_keys=True).encode()).hexdigest() == claimed

Análisis sin conexión: recopilar y analizar

ubuntils scan ejecuta la recopilación, la detección y la línea de tiempo juntas contra el host en vivo. collect y analyze dividen ese flujo de trabajo en dos: collect adquiere un paquete a prueba de manipulación de un host (no se ejecuta detección), y analyze ejecuta la misma línea de detección/línea de tiempo utilizada por scan contra un paquete, o contra una imagen montada mediante --root, sin requerir root y sin volver a tocar el host original. Esto es para casos en los que deseas adquirir artefactos una vez y analizarlos más tarde, en otro lugar o repetidamente — o cuando estás realizando un triaje de una imagen de disco en lugar de un sistema en ejecución.

`ubuntils collect````bash

sudo ubuntils collect --output /path/to/bundle.tar.gz

root@kitploit:~
Requiere root, como `scan`. Lee una lista fija de archivos (`/etc/passwd`, `/etc/group`, `/etc/shadow`, `/etc/sudoers`, `/etc/ld.so.preload`, `/etc/environment`, `/etc/crontab`, `/etc/profile`, `/var/log/syslog`, `/var/log/messages`, `/var/log/audit/audit.log`) y ejecuta una lista fija de comandos (`ss -tunap`, `netstat -tunap`, `systemctl list-timers` tanto en formato JSON como de texto, y `journalctl -o json` de los últimos 7 días), calcula el hash de cada elemento capturado y escribe todo, junto con un `manifest.json`, en un paquete `.tar.gz`. Los archivos de registro capturados y la salida de journalctl son lo que permite a `analyze BUNDLE` construir una línea de tiempo real sin conexión. Si se omite `--output`, el paquete se escribe en `./ubuntils-bundle-<UTC timestamp>.tar.gz` en el directorio actual.

### `ubuntils analyze````bash
ubuntils analyze BUNDLE.tar.gz [--json] [--output FILE] [--config FILE] [--baseline FILE] [--rules FILE] [--since TIME]
ubuntils analyze --root /mnt/forensic-image [--json] [--output FILE] [--config FILE] [--baseline FILE] [--rules FILE] [--since TIME]

Toma una ruta de bundle como argumento posicional o --root PATH apuntando a una imagen montada / árbol de sistema de archivos extraído — no ambos. Ejecuta el mismo motor de detección, reglas personalizadas, allowlist y lógica de baseline que usa scan. No requiere root. El bundle se extrae a un directorio temporal privado que se elimina tan pronto como finaliza el análisis (puede contener /etc/shadow).

La cobertura difiere entre los dos modos offline, porque un bundle lleva el estado capturado reproducido desde el momento de collect mientras que --root solo tiene lo que esté presente en el sistema de archivos montado:

  • analyze BUNDLE reproduce la salida real de los comandos ss/systemctl list-timers/journalctl capturada en el momento de collect, por lo que NetworkCollector y SystemdCollector producen hallazgos genuinos a partir de esa instantánea — no se omiten. La línea de tiempo se construye a partir del syslog/messages/audit.log/journalctl que el bundle capturó, por lo que está completamente poblada y los hallazgos obtienen una correlación real de related_events.
  • analyze --root PATH apunta a una imagen muerta, montada, sin proceso activo ni estado del kernel que consultar, por lo que la ejecución de comandos se deshabilita por completo: NetworkCollector y SystemdCollector se omiten, registrándose en scan_metadata.command_collectors_skipped. La línea de tiempo aún se construye, pero a partir de los archivos de log estáticos presentes en la imagen (/var/log/syslog, /var/log/messages, /var/log/audit/audit.log) — la reproducción de journald no está disponible aquí ya que no hay un journalctl activo para consultar una imagen muerta.

Consulta Offline analysis: collect and analyze para la lista completa de brechas de cobertura de detección offline.

Formato del bundle

Un bundle es un tarball comprimido con gzip con todo bajo un prefijo bundle/:``` bundle/ ├── manifest.json ├── files/ │ ├── etc/passwd │ ├── etc/shadow │ ├── var/log/syslog │ └── ... # every captured file, path-flattened under files/ └── commands/ ├── ss.txt ├── netstat.txt ├── systemctl_list_timers_json.txt ├── systemctl_list_timers_text.txt └── journalctl.txt

root@kitploit:~
Esquema de `manifest.json`:

| Campo | Tipo | Descripción |
|---|---|---|
| `run_id` | string | UUID generado de nuevo para cada ejecución de `collect` |
| `host_id` | string | Reservado para futura correlación multi-host; actualmente vacío |
| `hostname` | string | `socket.gethostname()` en el momento de la recolección |
| `ubuntu_version` | string | Cadena de versión de Ubuntu detectada |
| `collected_at_utc_start` / `collected_at_utc_end` | string (ISO 8601) | Límites de tiempo real de la ejecución de recolección |
| `tool_version` | string | Versión de ubuntils que produjo el bundle |
| `files[]` | array | Una entrada por archivo capturado: `source_path`, `bundle_path`, `sha256`, `size`, `mtime`, `ctime` (un archivo ausente o ilegible en el host de origen se registra con `sha256: ""`, `size: -1` en lugar de abortar la recolección) |
| `commands[]` | array | Una entrada por comando capturado: `name`, `argv`, `bundle_path`, `sha256`, `exit_code` |
| `bundle_sha256` | string | SHA-256 sobre el resto del manifiesto (todo lo anterior, serializado canónicamente) — el ancla de evidencia de manipulación para todo el bundle |

### Integridad del bundle en la salida JSON

`scan_metadata.bundle_integrity` de `analyze` reporta uno de tres valores:

- `"live"` — `scan` y `analyze --root` reportan esto; no hay bundle que verificar.
- `"ok"` — `analyze BUNDLE` verificó `bundle_sha256` contra el manifiesto y el SHA-256 de cada archivo capturado contra su contenido en el bundle; nada ha sido alterado desde que `collect` lo escribió.
- `"mismatch"` — el digest del manifiesto, el hash de un archivo capturado o el hash de la salida de un comando capturado no coincidieron. Algo en el bundle fue modificado, truncado o corrompido después de la recolección, y nada derivado de él debe considerarse limpio en cuanto a cadena de custodia. `analyze` aún produce su informe, pero imprime una advertencia roja en stderr, muestra un banner de integridad en la parte superior de la pestaña Summary de la TUI, y **sale con estado 3**, para que los scripts no puedan confundir los resultados de un bundle manipulado con resultados autoritativos.

### ⚠️ El análisis offline tiene lagunas de detección reales — lea esto antes de confiar en él

**Una ejecución de `analyze` con origen en un bundle o en `--root` no tiene paridad de detección con un `scan` en vivo.** Estos no son casos límite; son limitaciones estructurales de la adquisición estática y offline, y producen menos hallazgos (o ninguno) para las reglas afectadas en lugar de un error. Cuando un colector *sabe* que no pudo mirar (un comando fallido, un archivo ilegible), eso se registra en `scan_metadata.collectors_degraded` y se señala en la pestaña Summary de la TUI — pero un archivo que simplemente no fue capturado se ve igual que un archivo que no existe. (La línea de tiempo en sí ya *no* es una de estas lagunas: `analyze BUNDLE` reproduce el syslog/messages/audit.log/journalctl capturado desde el momento de `collect`, y `analyze --root` lee los archivos de log estáticos presentes en la imagen montada, por lo que ambos producen una línea de tiempo real y una correlación real de `related_events` — véase [`ubuntils analyze`](#ubuntils-analyze) más arriba.)

- **`PROCESS_MASQUERADE` y `PROCESS_SUSPICIOUS_CONNECTION` siempre reportarán cero hallazgos en modo offline.** Ambas reglas se basan en el campo `exe` de un proceso, que se completa leyendo el destino del enlace simbólico `/proc/<pid>/exe` a través de la fuente de artefactos (nunca el propio `/proc` del analista). Un bundle no tiene un `/proc` en vivo que leer, y `--root` apunta a un árbol de sistema de archivos montado que tampoco tiene `/proc` — actualmente no existe ningún mecanismo para capturar o reconstruir offline un destino de enlace simbólico de exe resuelto, por lo que `exe` siempre está vacío y ambas reglas nunca se activan, independientemente de lo que realmente haya en el host.
- **La enumeración de procesos no ocurre en absoluto offline.** `collect` no tiene un paso de captura por PID (`/proc/*/status`, `/proc/*/cmdline`), por lo que no existen procesos en un bundle que analizar en primer lugar — esta es la misma causa raíz que el punto anterior, desde el lado de la adquisición.
- **`CRON_TMP_PATH`, `SUDOERS_NOPASSWD` y `SSH_UNAUTHORIZED_KEY` están limitadas o ausentes en el análisis con origen en bundle.** La lista de archivos de `collect` es estática y no puede expandir con glob `/etc/cron.d/*`, `/etc/sudoers.d/*`, `/etc/profile.d/*`, ni `~/.ssh/authorized_keys` por usuario — solo se capturan `/etc/crontab`, `/etc/sudoers` y `/etc/environment`/`/etc/profile`. (`--root` contra un árbol de sistema de archivos montado completo no tiene esta laguna, ya que los directorios reales están presentes en el disco.) Cuando `SSH_UNAUTHORIZED_KEY` o `SHELL_RC_MODIFICATION` *sí* se activan (scan en vivo, o `--root` con los directorios reales por usuario presentes), ahora también puntúan la confianza a partir del ctime y el contenido del archivo, no solo del mtime — véase [Puntuación de confianza](#json-output) más abajo. Eso mejora cuánto debería confiar en un hallazgo que sí se activa; no cambia si la regla se activa offline en primer lugar.
- **La detección de `SUSPICIOUS_SYSTEMD_TIMER` está debilitada para bundles.** Las unidades de servicio se leen directamente de los directorios de unidades (`/etc/systemd/system`, `/usr/lib/systemd/system`, `~/.config/systemd/user` por usuario, …), por lo que `--root` obtiene cobertura completa de servicios. Un bundle no captura esos directorios, sin embargo: los timers aparecen a partir de la salida capturada de `systemctl list-timers`, pero el `ExecStart` de cada timer proviene de una llamada `systemctl show` por unidad que `collect` no realiza, por lo que la regla no puede evaluar qué ejecuta un timer incluido en el bundle.

**Cuándo importa:** si está triando un host en vivo y accesible, use `sudo ubuntils scan` — tiene cobertura de detección completa. Use `collect`/`analyze` cuando necesite adquirir una vez y analizar en otro lugar, necesite analizar sin root, o esté trabajando desde una imagen de disco donde `scan` no es una opción en absoluto — y trate un resultado limpio de `analyze` para las reglas anteriores como "no verificado", no como "verificado y limpio".

---

## La TUI

Ejecutar `sudo ubuntils scan` (sin `--json`) lanza una TUI interactiva a pantalla completa.

### Pantalla de escaneo

Mientras los colectores se ejecutan, ubuntils muestra una lista de verificación en vivo — una fila por colector. Cada fila se actualiza en tiempo real a medida que el colector termina:```
Scanning system…

  ✓  Process
  ✓  Network
  ✓  Users
  ⠹  Cron
     Systemd
     SSH
     Sudoers
     Environment

✓ marca éxito, ✗ marca fallo, el spinner marca el colector activo, y las filas en blanco están pendientes. Una vez que todos los colectores terminan y la detección + línea de tiempo se completan, la TUI cambia automáticamente a la pantalla de resultados.

Pantalla de resultados

La pantalla de resultados tiene cuatro pestañas que se navegan con las teclas numéricas:

TeclaPestañaContenido
1ResumenEstadísticas del escaneo + hallazgos principales de un vistazo
2HallazgosLista completa de hallazgos con detalle en línea y remediación
3Línea de tiempoEventos de registro correlacionados cronológicamente
4EstadísticasVersión de Ubuntu, arquitectura, duración, recuentos de colectores

Pulse q o Ctrl+C para salir.

Pestaña Resumen (tecla 1)

Muestra los metadatos del escaneo y los hallazgos principales en una sola pantalla:``` Collectors: 8 run · 0 failed Findings: 2 HIGH · 1 MEDIUM · 0 LOW Timeline: 47 events Duration: 2.8s

● HIGH CRON_TMP_PATH /etc/cron.d/cleanup ● HIGH LD_PRELOAD_INJECT /home/alice/.bashrc ○ MED SSH_UNAUTHORIZED_KEY /home/bob/.ssh/authorized_keys

root@kitploit:~
En un sistema limpio, esta pestaña muestra `System appears clean.`

### Pestaña Findings (tecla `2`)

Una lista desplazable de todos los hallazgos, ordenados de HIGH → MEDIUM → LOW. Al seleccionar un hallazgo (Enter o las teclas de flecha) se expande un panel de detalles en la parte inferior que muestra la descripción completa, la ruta del artefacto, el valor desencadenante sin procesar y la información de remediación.```
HIGH  CRON_TMP_PATH           /etc/cron.d/cleanup
HIGH  LD_PRELOAD_INJECT       /home/alice/.bashrc
MED   SSH_UNAUTHORIZED_KEY    /home/bob/.ssh/authorized_keys
───────────────────────────────────────────────────────
A cron job was found referencing /tmp, /var/tmp, or /dev/shm.
These directories are world-writable and commonly used as
attacker staging grounds.

Artifact:  /etc/cron.d/cleanup
Raw:       0 * * * * root /tmp/.update
Fix:       Will remove the offending cron entry from
           /etc/cron.d/cleanup after creating a timestamped backup.

R: remediate

Remediación dentro de la TUI

Para los hallazgos que tienen disponible una remediación automatizada, presione R mientras el hallazgo está seleccionado. Aparece un modal de confirmación:``` ┌─────────────────────────────────────────────────┐ │ Remediate CRON_TMP_PATH? │ │ │ │ Will remove the offending cron entry from │ │ /etc/cron.d/cleanup after creating a backup. │ │ Backup will be created at /var/backups/ubuntils/…│ │ │ │ Y: confirm Esc: cancel │ └─────────────────────────────────────────────────┘

root@kitploit:~
Pulsa `Y` para confirmar. El remediador se ejecuta en un hilo en segundo plano. Cuando finaliza, la fila del hallazgo en la lista se actualiza a `[fixed]` y el panel de detalles muestra el resultado:```
✓ Remediated
Backup:    /var/backups/ubuntils/20260115_142201/etc_cron.d_cleanup
Rollback:  cp /var/backups/ubuntils/20260115_142201/etc_cron.d_cleanup /etc/cron.d/cleanup

En caso de fallo, el panel de detalles muestra el error. La copia de seguridad siempre se crea antes de intentar cualquier cambio.

Pulse Esc para contraer el panel de detalles.

Pestaña Timeline (tecla 3)

Una lista cronológica desplazable de eventos de registro correlacionados. Cada fila muestra la marca de tiempo, el origen y la descripción. Los eventos se extraen de syslog, journald y auditd y se deduplican.

Pestaña Stats (tecla 4)

Una vista resumida del escaneo: versión de Ubuntu detectada, arquitectura, duración del escaneo, número de recopiladores y fallos, y recuento de hallazgos por severidad junto con el total de eventos de la línea de tiempo.


Qué detecta

ID de reglaSeveridadSubsanableQué comprueba
CRON_ROOT_EXECHIGHSíCrontabs de usuarios no root que ejecutan comandos en rutas propiedad de root o incluyen sudo en línea
CRON_TMP_PATHHIGHSí*Cualquier tarea cron (incluidas las entradas @reboot/@daily y los scripts en /etc/cron.{hourly,daily,weekly,monthly}) que haga referencia a /tmp, /var/tmp o /dev/shm. *Las líneas de script son solo de marcado
LD_PRELOAD_INJECTHIGHSíCualquier entrada en /etc/ld.so.preload (vacío en Ubuntu estándar), o LD_PRELOAD en cualquier archivo de inicio de shell con cualquier biblioteca listada fuera de /lib, /usr/lib, /lib64, /usr/lib64
SUSPICIOUS_SYSTEMD_TIMERHIGHNoTemporizadores de systemd y unidades de servicio cuyo ExecStart haga referencia a un directorio con permisos de escritura para todos o ejecute un binario que no sea propiedad de root
SSH_UNAUTHORIZED_KEYMEDIUMSíArchivos authorized_keys modificados en los últimos 7 días
USER_UID_ZEROHIGHNoCualquier cuenta distinta de root con UID 0 (un segundo superusuario oculto)
USER_EMPTY_PASSWORDHIGHNoUna cuenta con shell de inicio de sesión cuyo campo de contraseña en /etc/shadow esté vacío (el nullok predeterminado de PAM en Ubuntu permite iniciar sesión sin contraseña)
SUDOERS_NOPASSWDMEDIUMSí*Concesiones NOPASSWD en sudoers para usuarios con UID ≥ 1000 y shell de inicio de sesión, directamente o mediante una regla %group; se siguen los archivos incluidos. *Las reglas de grupo son solo de marcado (eliminar %sudo podría eliminar todo el acceso a sudo)
PROCESS_MASQUERADEMEDIUMNoProcesos cuyo nombre coincide con un binario conocido del sistema pero cuyo ejecutable está fuera de los directorios estándar del sistema (/usr/bin, /usr/sbin, /bin, /sbin, /usr/local/{bin,sbin}, /usr/lib, /usr/libexec, /lib, /snap)
PROCESS_SUSPICIOUS_CONNECTIONHIGH / MEDIUMNoProcesos que mantienen una conexión saliente cuyo ejecutable está en un directorio temporal con permisos de escritura para todos o ha sido eliminado del disco (HIGH), o está fuera de los directorios estándar del sistema o se comunica con un puerto remoto no estándar (MEDIUM)

Por qué existe cada regla

CRON_ROOT_EXEC — Los crontabs de usuario se ejecutan como el propietario del crontab. Una entrada que invoca sudo o un intérprete propiedad de root significa que el usuario ha dispuesto que se ejecute código con privilegios de root de forma programada, sin necesidad de acceso sudo persistente. Esto sobrevive a los cambios de contraseña.

Ejemplo de hallazgo:``` [HIGH] CRON_ROOT_EXEC Title: User crontab executing with sudo Artifact: /var/spool/cron/crontabs/alice Raw value: */5 * * * * sudo /usr/bin/python3 /tmp/beacon.py Remediation: available

root@kitploit:~
**CRON_TMP_PATH** — Los directorios con permisos de escritura para todos, como /tmp y /dev/shm, son zonas de preparación estándar para atacantes. Un trabajo cron que apunta allí significa que un payload puede ser sustituido entre invocaciones sin tocar ninguna ruta persistente. Esto cubre las entradas de estilo `@reboot`/`@daily` y los scripts en `/etc/cron.{hourly,daily,weekly,monthly}`; los hallazgos sobre esos scripts son solo de marcado, ya que eliminar una línea de un script de shell no es una corrección automática segura.

*Ejemplo de hallazgo:*```
[HIGH] CRON_TMP_PATH
Title:         Cron job references writable temp directory
Artifact:      /etc/cron.d/cleanup
Raw value:     0 * * * * root /tmp/.update
Remediation:   available

LD_PRELOAD_INJECT — LD_PRELOAD hace que el enlazador dinámico cargue una biblioteca compartida especificada antes que todas las demás, lo que permite la interceptación arbitraria de funciones en cualquier binario enlazado dinámicamente. Un valor que apunte fuera de las rutas de bibliotecas estándar es un indicador de rootkit en espacio de usuario casi seguro; se verifica cada biblioteca en una lista separada por espacios o dos puntos. /etc/ld.so.preload se inyecta en todos los procesos y está vacío en Ubuntu estándar, por lo que cualquier entrada allí se reporta — incluso una colocada dentro de /lib, un truco común de rootkit. La remediación elimina las entradas de /etc/ld.so.preload en lugar de comentarlas, porque el cargador no tiene sintaxis de comentarios en ese archivo.

Ejemplo de hallazgo:``` [HIGH] LD_PRELOAD_INJECT Title: LD_PRELOAD set to non-standard library path Artifact: /home/alice/.bashrc Raw value: export LD_PRELOAD=/tmp/.libssl.so Remediation: available

root@kitploit:~
**SUSPICIOUS_SYSTEMD_TIMER** — Los temporizadores de Systemd son más persistentes y menos visibles que los trabajos de cron para la mayoría de los respondedores. Un temporizador — o una unidad `.service` simple, que es la persistencia más común y no necesita ningún temporizador — cuyo ExecStart haga referencia a un directorio temporal o ejecute un binario que no sea propiedad de root es señal de persistencia creada por el atacante. Las unidades de servicio se leen directamente de los directorios de unidades, incluido el directorio por usuario `~/.config/systemd/user`. Solo marca — la eliminación de unidades de systemd requiere criterio humano.

*Ejemplo de hallazgo:*```
[HIGH] SUSPICIOUS_SYSTEMD_TIMER
Title:         Systemd timer ExecStart points to suspicious path
Artifact:      /etc/systemd/system/update-check.timer
Raw value:     ExecStart=/tmp/.sys/update
Remediation:   not available

SSH_UNAUTHORIZED_KEY — Una clave SSH recién añadida otorga acceso remoto persistente independientemente de las contraseñas. La ventana de 7 días detecta adiciones recientes mientras evita el ruido del aprovisionamiento inicial en sistemas más antiguos. Nota: la regla utiliza el mtime del archivo, que refleja la última escritura en el archivo authorized_keys, no la marca de tiempo de inserción de cada clave individual.

Ejemplo de hallazgo:``` [MEDIUM] SSH_UNAUTHORIZED_KEY Title: SSH authorized key added in last 7 days Artifact: /home/bob/.ssh/authorized_keys Raw value: ssh-rsa AAAAB3NzaC1... attacker@evil Remediation: available

root@kitploit:~
**SUDOERS_NOPASSWD** — sudo sin contraseña para una cuenta de usuario humana (UID ≥ 1000 con un shell de inicio de sesión) es un vector de escalada de privilegios que sobrevive a la eliminación de otros mecanismos de persistencia. Las concesiones NOPASSWD legítimas son casi siempre para cuentas de servicio sin shell de inicio de sesión. Las reglas de grupo (`%sudo ALL=(ALL) NOPASSWD:ALL`) se resuelven a sus miembros, y los archivos `#include`/`@includedir` se siguen. Los hallazgos de grupo son solo de marcado: eliminar una regla como `%sudo` podría eliminar todas las concesiones de sudo en el sistema.

*Ejemplo de hallazgo:*```
[MEDIUM] SUDOERS_NOPASSWD
Title:         NOPASSWD sudo grant for regular user
Artifact:      /etc/sudoers.d/alice
Raw value:     alice ALL=(ALL) NOPASSWD: ALL
Remediation:   available

PROCESS_MASQUERADE — Nombrar un binario malicioso con el nombre de un proceso del sistema conocido (sshd, python3, bash) es una técnica básica para evitar la detección en la salida de ps. Esta regla cruza el nombre del proceso de /proc/<pid>/status con la ruta resuelta del ejecutable de /proc/<pid>/exe. Las ubicaciones estándar incluyen /usr/local/{bin,sbin}, /usr/lib, /usr/libexec y /snap, por lo que systemd (/usr/lib/systemd/systemd) y los paquetes snap no la activan. Solo marca — matar un proceso requiere criterio humano.

Ejemplo de hallazgo:``` [MEDIUM] PROCESS_MASQUERADE Title: Process masquerading as system binary Artifact: /proc/1337/exe Raw value: name=sshd, exe=/tmp/.sshd Remediation: not available

root@kitploit:~
**USER_UID_ZERO** — Solo `root` debería tener el UID 0. Una segunda cuenta asignada al UID 0 (CIS Ubuntu Benchmark 6.2.x) es una puerta trasera de alta confianza: otorga derechos de superusuario completos sin alterar las propias credenciales de root, y sobrevive a un restablecimiento de la contraseña de root. Tasa de falsos positivos casi nula. Solo marcado — eliminar una cuenta con UID 0 requiere criterio humano.

*Ejemplo de hallazgo:*```
[HIGH] USER_UID_ZERO
Title:         Non-root account with UID 0
Artifact:      /etc/passwd
Raw value:     toor:x:0:0:...:/bin/bash
Remediation:   not available

USER_EMPTY_PASSWORD — Una cuenta cuyo campo de contraseña en /etc/shadow está vacío no tiene contraseña alguna, y la pila PAM predeterminada de Ubuntu (pam_unix ... nullok) le permite iniciar sesión sin una. En una cuenta con un shell de inicio de sesión, eso es una puerta abierta. Solo marca — bloquéala con passwd -l mientras investigas.

Ejemplo de hallazgo:``` [HIGH] USER_EMPTY_PASSWORD Title: Login account with no password Artifact: /etc/shadow Raw value: eve:: Remediation: not available

root@kitploit:~
**PROCESS_SUSPICIOUS_CONNECTION** — La persistencia es solo la mitad del panorama; un punto de apoyo que nunca se comunica con nada rara vez es el que te importa. Esta regla une los recolectores de procesos y de red por PID, de modo que un proceso marcado llega con sus conexiones actuales adjuntas. Un ejecutable preparado en `/tmp` que mantiene un socket saliente establecido es HIGH; un binario legítimo que alcanza un puerto remoto no estándar es MEDIUM y merece una revisión. Esta es una instantánea del estado actual, no un monitoreo continuo — un beacon que está dormido cuando escaneas no aparecerá. Solo marcado.

*Ejemplo de hallazgo:*```
[HIGH] PROCESS_SUSPICIOUS_CONNECTION
Title:         Process with suspicious outbound connection
Artifact:      /proc/1337/exe
Raw value:     203.0.113.9:4444
Remediation:   not available

SHELL_RC_MODIFICATION — Los archivos de inicialización del shell son un vector de persistencia fiable porque se ejecutan en cada inicio de sesión del usuario. Esta regla muestra las modificaciones recientes para revisión humana. Solo marca — el contenido del RC del shell requiere lectura antes de actuar sobre él.

Ejemplo de hallazgo:``` [LOW] SHELL_RC_MODIFICATION Title: Shell init file recently modified Artifact: /root/.bashrc Raw value: mtime=2024-01-15 14:22:01 (6 hours ago) Remediation: not available

root@kitploit:~
**PACKAGE_TAMPERED** — Los binarios y archivos de configuración propiedad del sistema son la base de la confianza. Esta regla detecta cuándo los archivos propiedad de paquetes han sido modificados, eliminados o presentan discrepancias de contenido/modo/tamaño usando `dpkg --verify`. Las ediciones solo de conffile (cambios de configuración local esperados) se excluyen del reporte para evitar ruido. Solo marca — la manipulación puede ser legítima (ediciones locales personalizadas) o maliciosa (reemplazo de archivo); decidir requiere juicio humano.

*Ejemplo de hallazgo:*```
[HIGH] PACKAGE_TAMPERED
Title:         Package-owned file modified since installation
Artifact:      /usr/bin/sshd
Raw value:     ....5..T. (content and mtime differ)
Remediation:   not available

IMMUTABLE_FLAG_SET — Los atacantes a menudo establecen el flag inmutable (i) o el flag de solo anexado (a) en archivos para impedir su modificación o eliminación, incluso por root, incluyendo para ocultar la manipulación de ediciones posteriores o la rotación de logs. Establecer estos flags en archivos sensibles del sistema como /etc/passwd, /etc/sudoers, /etc/pam.d/*, o los archivos de log auth/syslog/wtmp/btmp es un fuerte indicador de endurecimiento por parte del atacante. Esta regla detecta los flags inmutable y de solo anexado mediante lsattr contra esa lista fija de rutas sensibles. Solo flag — los cambios de flag requieren revisión humana.

Ejemplo de hallazgo:``` [MEDIUM] IMMUTABLE_FLAG_SET Title: Sensitive file has an unexpected chattr flag Artifact: /etc/ld.so.preload Raw value: ----i--------e--- Remediation: not available

root@kitploit:~
**PAM_BACKDOOR** — PAM (Pluggable Authentication Modules) y NSS (Name Service Switch) son los sistemas centrales de autenticación e identidad en Linux. Esta regla NO realiza detección basada en mtime de "¿fue modificado este archivo?" — compara patrones en el *contenido* del archivo: (1) una línea literal `pam_permit.so` en cualquier archivo /etc/pam.d/* (este módulo siempre tiene éxito y es un backdoor clásico de omisión de autenticación), o (2) un módulo NSS listado en /etc/nsswitch.conf que no está en la lista de permitidos integrada de ubuntils. **Nota:** la comprobación de NSS dará falsos positivos en hosts unidos a dominio/SSSD/LDAP/Winbind que usen un módulo fuera de la lista de permitidos integrada — por esta razón se puntúa intencionalmente con menor confianza que la coincidencia de pam_permit.so; use `--config` para permitir nombres de módulos no reconocidos en su entorno. Solo marcado — los cambios en la configuración de autenticación requieren una verificación cuidadosa.

*Hallazgos de ejemplo:*```
[HIGH] PAM_BACKDOOR
Title:         PAM config unconditionally permits authentication
Artifact:      /etc/pam.d/sshd
Raw value:     auth required pam_permit.so
Remediation:   not available
root@kitploit:~
[HIGH] PAM_BACKDOOR
Title:         Unexpected NSS module in nsswitch.conf
Artifact:      /etc/nsswitch.conf
Raw value:     passwd: files evilmod
Remediation:   not available

KERNEL_MODULE_SUSPICIOUS — Los módulos del kernel se ejecutan en ring 0 con acceso sin restricciones. Los atacantes cargan con frecuencia módulos del kernel personalizados para rootkits, sniffing de paquetes u ocultación de procesos. Esta regla compara los módulos cargados actualmente con una pequeña lista de permitidos de módulos integrados esperados (comunes en la mayoría de los sistemas). Es de severidad LOW porque esa lista de permitidos es deliberadamente reducida. Nota: los hosts con mucho hardware, como controladores de GPU, tarjetas Wi-Fi o controladores propietarios, generarán falsos positivos. Los respondedores deben agregar los módulos esperados de su host mediante --config, permitiéndolos por nombre de módulo (usado como artifact_path). Solo marcado — la investigación de módulos del kernel requiere herramientas forenses y experiencia humana.

Ejemplo de hallazgo:``` [LOW] KERNEL_MODULE_SUSPICIOUS Title: Loaded kernel module not in the expected set Artifact: implant_rootkit Raw value: {'name': 'implant_rootkit', 'size': '12288', 'used_by': []} Remediation: not available

root@kitploit:~
**SETUID_INVENTORY** — Los binarios setuid y setgid escalan privilegios automáticamente cuando se ejecutan. Los atacantes crean binarios setuid/setgid personalizados para persistir la escalada de privilegios, con mayor frecuencia fuera de los directorios estándar de binarios del sistema (una ruta de instalación convencional como /opt, el propio /home de un usuario, /srv, o un directorio temporal con permisos de escritura para todos). Esta regla inventaría los binarios setuid/setgid mediante `find -perm -4000 -o -perm -2000` en `/usr /bin /sbin /opt /home /srv /tmp /var/tmp /dev/shm` y marca cualquiera que esté fuera de un conjunto de referencia conocido de utilidades legítimas del sistema. Solo marca — los binarios setuid/setgid inesperados requieren investigación, pero pueden ser binarios legítimos instalados por aplicaciones.

*Ejemplo de hallazgo:*```
[LOW] SETUID_INVENTORY
Title:         Unexpected setuid binary
Artifact:      /tmp/.hidden/backdoor
Raw value:     setuid
Remediation:   not available

Salida JSON

--json escribe un único objeto JSON en stdout. No se imprime nada más.```json { "scan_metadata": { "tool_version": "2.1.0", "hostname": "web-01", "generated_at": "2026-06-10T08:22:03.114523+00:00", "ubuntu_version": "Ubuntu 22.04.3 LTS", "architecture": "x86_64", "duration_s": 2.84, "collector_failures": 0, "bundle_integrity": "live", "command_collectors_skipped": [], "collectors_degraded": {}, "rules_failed": [], "timeline_error": null, "suppressed_by_baseline": 1 }, "artifact_counts": { "ProcessCollector": 142, "NetworkCollector": 23, "UserCollector": 4, "CronCollector": 7, "SystemdCollector": 12, "SSHCollector": 3, "SudoersCollector": 5, "EnvironmentCollector": 18 }, "findings": [ { "rule_id": "CRON_TMP_PATH", "severity": "HIGH", "title": "Cron job references writable temp directory", "description": "A cron job was found referencing /tmp, /var/tmp, or /dev/shm. These directories are world-writable and commonly used as attacker staging grounds.", "artifact_path": "/etc/cron.d/cleanup", "raw_value": "0 * * * * root /tmp/.update", "remediation_available": true, "remediation_description": "Will remove the offending cron entry from /etc/cron.d/cleanup after creating a timestamped backup.", "related_events": [ { "timestamp": "2024-01-15T08:20:00+00:00", "source": "syslog", "description": "CRON[2841]: (root) CMD (/tmp/.update)" } ], "confidence": 75, "confidence_band": "HIGH", "signals": [ {"name": "timeline_corroboration", "weight": 25, "detail": "1 nearby timeline event(s)"} ] }, { "rule_id": "PROCESS_MASQUERADE", "severity": "MEDIUM", "title": "Process masquerading as system binary", "description": "Process 'sshd' (pid=1337) has exe path outside standard binary directories: /tmp/.sshd", "artifact_path": "/proc/1337/exe", "raw_value": "/tmp/.sshd", "remediation_available": false, "guided_remediation": "Confirm pid 1337 is malicious (ls -l /proc/1337/exe, cat /proc/1337/cmdline), then terminate it: kill -9 1337.", "confidence": 50, "confidence_band": "MEDIUM", "signals": [] } ], "timeline": [ { "timestamp": "2024-01-15T08:22:01+00:00", "source": "syslog", "description": "sshd: Accepted publickey for alice from 10.0.0.42 port 52341" } ], "report_sha256": "a3f1c9…(64 hex chars)" }

root@kitploit:~
`remediation_results` aparece como una clave adicional de nivel superior solo cuando se pasa `--remediate`. `report_sha256` siempre está presente y se calcula sobre el resto del documento. `scan_metadata.bundle_integrity` es `"live"` para `scan` y `analyze --root`, `"ok"` para un bundle verificado pasado a `analyze`, y `"mismatch"` si el contenido de un bundle no coincide con su manifiesto — consulta [Integridad del bundle en la salida JSON](#bundle-integrity-in-json-output). `scan_metadata.command_collectors_skipped` nombra cualquier colector basado en comandos (`NetworkCollector`, `SystemdCollector`, `PackageCollector`, `KernelCollector`) omitido en una ejecución con `--root` — siempre vacío para `scan` y `analyze BUNDLE`. `scan_metadata.suppressed_by_baseline` es el recuento de hallazgos que un archivo `--baseline` eliminó de este informe — consulta [Línea base de estado conocido](#known-good-baselining---baseline). `scan_metadata.collectors_degraded` asigna un nombre de colector a los motivos por los que sus datos están incompletos (un comando que falló o agotó el tiempo de espera, un archivo ilegible, una línea malformada omitida), `rules_failed` enumera cualquier regla de detección que falló, y `timeline_error` se establece si no se pudo construir la línea de tiempo. Los tres están vacíos en una ejecución saludable. Compruébalos antes de interpretar una lista de hallazgos vacía como "limpio".

`related_events` y `guided_remediation` aparecen en un hallazgo solo cuando tienen contenido. `related_events` contiene hasta cinco eventos de la línea de tiempo emparejados con el hallazgo por ruta de artefacto y palabras clave de la regla, los más recientes primero — una ayuda para sacar a la superficie, no una afirmación causal. `guided_remediation` es una secuencia de comandos revisada para que la ejecutes manualmente; ubuntils nunca la ejecuta.

### Puntuación de confianza

Cada hallazgo lleva una puntuación `confidence` (0–100, por defecto 50) y una `confidence_band` (`HIGH` ≥ 75, `MEDIUM` ≥ 40, `LOW` por debajo de eso), además de una lista `signals` que muestra exactamente cómo se alcanzó esa puntuación — cada entrada es `{"name", "weight", "detail"}`, así que la puntuación siempre es explicable, nunca una caja negra. Las señales son aditivas sobre una confianza base de 50 y las aplica la regla o etapa del pipeline que las produjo:

- Las reglas de detección aplican sus propias señales en el momento del hallazgo — p. ej. `SSH_UNAUTHORIZED_KEY` y `SHELL_RC_MODIFICATION` añaden `content_match` (+30) cuando el contenido del artefacto coincide con un patrón conocido como peligroso (una opción peligrosa de clave SSH; una línea curl/wget-a-shell o base64-decode en un archivo RC de shell), `ctime_corroborates_mtime` (+20) cuando el ctime del archivo también está dentro de la ventana de detección (más difícil de falsificar que el mtime por sí solo), o `mtime_only` (−20) cuando la recencia es la *única* señal y el ctime no la corrobora — una pista de que el mtime puede haber sido retrasado.
- El pipeline aplica `timeline_corroboration` (+25) tras la correlación hallazgo↔línea de tiempo, cuando un hallazgo tiene uno o más `related_events`.

Un hallazgo de banda `LOW` no se descarta ni se oculta — sigue apareciendo en la lista de hallazgos y en la salida JSON exactamente igual que cualquier otro — pero la banda te indica cuánto peso darle antes de investigar más a fondo. Esto reemplaza la antigua heurística basada solo en mtime para `SSH_UNAUTHORIZED_KEY`/`SHELL_RC_MODIFICATION`, donde un archivo obsoleto pero tocado legítimamente (p. ej. una herramienta de gestión de configuración que reescribe `.bashrc` en cada ejecución) parecía idéntico a un backdoor genuinamente nuevo.

**Limitación conocida:** hoy solo están activas las señales de patrón de contenido y ctime. Las señales basadas en propiedad/huella — una huella de clave SSH desconocida, la opción de restricción `from=` de una clave, o una discrepancia de propietario/modo en un archivo RC (una señal `ownership_anomaly`) — aún no están implementadas. Es una brecha de cobertura diferida, registrada para una versión futura, no algo que la puntuación de confianza actual tenga en cuenta.

---

## Remediación

Cinco de las dieciséis reglas de detección tienen remediación automatizada: `CRON_ROOT_EXEC`, `CRON_TMP_PATH`, `LD_PRELOAD_INJECT`, `SSH_UNAUTHORIZED_KEY` y `SUDOERS_NOPASSWD`. El resto son solo de marcado y nunca se remediarán automáticamente, porque actuar sobre ellas de forma segura requiere que una persona lo revise primero.

### Remediación guiada

`SUSPICIOUS_SYSTEMD_TIMER`, `PROCESS_MASQUERADE` y `SHELL_RC_MODIFICATION` llevan una cadena `guided_remediation`: los comandos exactos a ejecutar una vez que hayas confirmado el hallazgo — `systemctl disable --now <unit>`, `kill -9 <pid>`, o la revisión y reversión del archivo RC. Se muestra en el panel de detalle de la TUI y en JSON. ubuntils nunca la ejecuta por ti; estas reglas quedan fuera del barrido `--remediate --confirm` por diseño.

### En la TUI

Selecciona cualquier hallazgo con una remediación en la pestaña Findings, luego pulsa `R`. Un modal de confirmación previsualiza la acción planificada. Pulsa `Y` para aplicarla — el remediador se ejecuta en un hilo en segundo plano para que la TUI siga respondiendo. La fila del hallazgo se actualiza a `[fixed]` cuando termina, con la ruta de la copia de seguridad y el comando de reversión exacto mostrados en línea.

### Desde la CLI

`--remediate` sin `--confirm` es una ejecución en seco segura: se crean copias de seguridad y se ejecuta la validación, pero no se aplica ningún cambio. Pasa ambos flags para realizar cambios realmente. El pipeline se ejecuta antes de que se lance la TUI en este modo, y la pestaña Summary enumera cada resultado de remediación con su ruta de copia de seguridad y comando de reversión.

`--remediate --confirm` solo actúa sobre hallazgos con una puntuación de confianza de al menos 40 (la banda MEDIUM) — un `SSH_UNAUTHORIZED_KEY` de baja confianza y solo mtime se reporta como `SKIPPED` en lugar de eliminar su clave. Ajusta el umbral con `--min-confidence N`.```bash
sudo ubuntils scan --remediate          # dry run
sudo ubuntils scan --remediate --confirm # apply changes, then open TUI
sudo ubuntils scan --remediate --confirm --min-confidence 75  # only HIGH-confidence findings

Salvaguardas

Cada remediación sigue el mismo patrón independientemente de cómo se active:

  1. Detectar si la ruta del artefacto es un enlace simbólico — rechazar si lo es (evita que root escriba a través de enlaces simbólicos controlados por el atacante)
  2. Crear una copia de seguridad con marca de tiempo en /var/backups/ubuntils/YYYYMMDD_HHMMSS/ con modo 0700
  3. Validar el estado actual (la línea exacta debe seguir presente)
  4. Aplicar el cambio mínimo posible — las entradas de cron y las claves se eliminan línea por línea; las líneas LD_PRELOAD en los archivos de inicio del shell se comentan; las entradas en /etc/ld.so.preload se eliminan (el cargador no tiene sintaxis de comentarios allí, por lo que una entrada comentada aún se cargaría). Para sudoers, el contenido editado se verifica con visudo -cf en una copia temporal antes de tocar el archivo real
  5. Escribir de forma atómica — el nuevo contenido va a un archivo temporal junto al original (mismo modo y propietario), se hace fsync, y luego se renombra sobre él, de modo que un fallo a mitad de escritura no puede dejar un /etc/sudoers truncado
  6. Verificar que la línea exacta ya no está

Si algún paso falla, la remediación se detiene inmediatamente, el sistema queda sin cambios, y se reporta el error completo con la ruta de la copia de seguridad y el comando de reversión. El acceso sudo está protegido de dos maneras: las reglas NOPASSWD de %group (como %sudo) son solo de marcado y nunca se eliminan automáticamente, y el remediador de sudoers se niega a eliminar la última regla del archivo sudoers principal.


Integración con Wazuh

ubuntils está diseñado para un triaje de un solo host y en un momento puntual — lo ejecutas cuando ya sospechas que algo va mal, y nunca se comunica con el exterior ni sigue vigilando después de que termina el escaneo. Eso es deliberado, pero también significa que un hallazgo de ubuntils vive solo en ese informe a menos que algo lo lleve más allá. La mayoría de los equipos que ejecutan Ubuntu a cualquier escala ya tienen un SIEM haciendo el lado continuo de la detección, así que en lugar de convertir ubuntils en su propio agente de monitorización de larga duración, entrega sus hallazgos al que probablemente ya ejecutas: Wazuh.

Si hay un agente de Wazuh presente en el host (existe /var/ossec/bin/wazuh-agentd o /var/ossec/etc/ossec.conf), ubuntils scan (a menos que se ejecute con --no-wazuh) añade cada hallazgo como una línea JSON a /var/log/ubuntils/wazuh-alerts.json para que el agente lo recoja — esto es un reenviador puro, no un módulo de Wazuh: sin llamada de red, sin clave de API, nada más que las mismas escrituras de artefactos locales que ubuntils ya realiza — aunque el agente, por supuesto, enviará esas líneas fuera del host a su gestor; ese es el objetivo. Se autodetecta sin necesidad de ningún flag (usa --no-wazuh para excluir una ejecución), de modo que un ubuntils scan programado o por script en una flota de hosts enrolados con el agente empieza a alimentar el SIEM inmediatamente sin cableado adicional. Esto nunca ocurre durante el ubuntils analyze offline (bundle o --root), ya que esos hallazgos describen un host diferente al que ejecuta el agente local de Wazuh — reenviar los hallazgos de un bundle al propio agente del analista los atribuiría a la máquina equivocada.

La intención es integrar ubuntils en una canalización de alertas/escalado existente en lugar de pedirle a un respondedor que cuide de una segunda herramienta: una vez cargadas las reglas de ejemplo de abajo, un hallazgo de ubuntils de severidad HIGH (una nueva cuenta UID-0, un rootkit LD_PRELOAD, una puerta trasera PAM) aparece como una alerta normal de Wazuh, hereda cualquier enrutamiento de notificaciones que el gestor ya tenga configurado, y se sitúa junto a cualquier otra señal en la misma línea temporal en lugar de en un archivo JSON independiente que alguien tiene que recordar revisar.

Para que Wazuh analice y genere alertas sobre estos hallazgos, copia las reglas de ejemplo de examples/wazuh/ en tu gestor de Wazuh, y añade el bloque <localfile> de examples/wazuh/ossec_localfile_snippet.xml al /var/ossec/etc/ossec.conf del agente. No se necesita instalar ningún decodificador personalizado: el localfile está configurado con log_format json, por lo que el decodificador JSON integrado de Wazuh analiza cada línea y mapea cada clave JSON de nivel superior k a data.k, con lo que local_rules.xml coincide directamente.

  1. examples/wazuh/local_rules.xml → /var/ossec/etc/rules/ del gestor
  2. El bloque <localfile> de examples/wazuh/ossec_localfile_snippet.xml → /var/ossec/etc/ossec.conf del agente
  3. Reinicia ambos: systemctl restart wazuh-manager (gestor), systemctl restart wazuh-agent (host del agente)

Estas son solo plantillas de ejemplo, proporcionadas como punto de partida — no han sido probadas contra un gestor de Wazuh en vivo y deberían verificarse en un entorno que no sea de producción antes de confiar en ellas.

Esquema JSON por línea:

CampoTipoDescripción
timestampstring (ISO 8601)Cuándo se reenvió el hallazgo
hostnamestringEl host escaneado
rule_idstringCoincide con el ID de regla de detección de ubuntils (ver la tabla de Reglas de Detección arriba)
severitystringHIGH | MEDIUM | LOW
titlestringTítulo corto legible por humanos
descriptionstringDescripción completa del hallazgo
artifact_pathstringRuta del archivo/recurso donde se encontró el problema
raw_valuestringLa línea/valor sin procesar que activó la regla
remediation_availableboolSi ubuntils tiene un remediador para esta regla
related_eventsarray (opcional)Eventos de línea temporal correlacionados, si los hay

Recolectores

RecolectorArtefactos recopilados
ProcessCollectorProcesos en ejecución desde /proc y la salida de ps
NetworkCollectorConexiones abiertas y listeners desde ss/netstat
UserCollector/etc/passwd, /etc/shadow, /etc/group
CronCollectorDirectorios /etc/cron* y /var/spool/cron/crontabs/*
SystemdCollectorSalida de systemctl list-timers y list-units
SSHCollector~/.ssh/authorized_keys para todos los usuarios
SudoersCollector/etc/sudoers y todos los archivos bajo /etc/sudoers.d/
EnvironmentCollector/etc/environment, /etc/profile.d/*, archivos de inicio del shell de usuario
PackageCollectorIntegridad de paquetes del sistema vía dpkg --verify, atributos de flag inmutable vía lsattr, y binarios setuid/setgid vía find
PamCollectorArchivos /etc/pam.d/* y /etc/nsswitch.conf
KernelCollectorMódulos del kernel cargados vía lsmod

Dependencias de los recolectores

PackageCollector requiere tres herramientas estándar de Ubuntu en el host en vivo (dpkg, lsattr, find — todas presentes en instalaciones estándar de Ubuntu). Si algún comando no está disponible, PackageCollector produce grácilmente datos vacíos para esa porción en lugar de fallar. El análisis offline (analyze BUNDLE) reproduce la salida de comandos capturada en el momento de collect, por lo que no se requiere la disponibilidad de comandos en el host del analizador.

El escaneo find de setuid/setgid pasa -xdev para mantenerse acotado — no desciende a sistemas de archivos montados por separado (un montaje distinto bajo /opt, un /home montado por NFS, etc.). Esto es un compromiso deliberado entre tiempo de ejecución y cobertura: sin -xdev, el escaneo podría colgarse escaneando montajes de red o sistemas de archivos virtuales. Si tu entorno monta estas rutas en sistemas de archivos separados, ten en cuenta que no serán escaneadas.

dpkg --verify y el escaneo find de setuid/setgid usan tiempos de espera generosos no predeterminados (10 minutos y 5 minutos respectivamente, ver ubuntils/collectors/packages.py) ya que ambos pueden legítimamente ejecutarse bastante más allá del valor predeterminado de la biblioteca de 30 segundos en un host real con una base de datos de paquetes o árbol de archivos grande; ubuntils collect usa los mismos tiempos de espera al capturar estos comandos en un bundle.


Compatibilidad

Soportado
Ubuntu20.04, 22.04, 24.04
Arquitecturaamd64, arm64
Python3.9+
PrivilegiosSe requiere root para acceso completo a los artefactos

Ejecutar sin root produce un escaneo parcial con advertencias. Rutas críticas como /etc/shadow, directorios de crontab protegidos, y algunas entradas de /proc serán omitidas.


Hoja de ruta

v1.0.0

  • Los 8 recolectores
  • Las 8 reglas de detección
  • Constructor de línea temporal (syslog, journald, auditd)
  • Pantalla de progreso de escaneo en vivo con ✓/✗ por recolector
  • TUI interactiva de cuatro pestañas (Summary / Findings / Timeline / Stats)
  • Remediación dentro de la TUI con modal de confirmación y worker en segundo plano
  • Modo de salida JSON
  • Remediación por CLI para 5 reglas con copia de seguridad, reversión y protección contra enlaces simbólicos
  • Soporte para Ubuntu 20.04/22.04/24.04
  • 240 pruebas con 90% de cobertura

v1.1.0

  • Lista de permitidos de falsos positivos por id de regla o ruta (--config)
  • --output FILE para escribir informes directamente
  • Ventana temporal con --since
  • Informes a prueba de manipulación (report_sha256, hostname, timestamp)
  • Regla de detección USER_UID_ZERO

v1.5.0

  • Reglas de detección personalizadas por coincidencia de patrones vía YAML (--rules)
  • PROCESS_SUSPICIOUS_CONNECTION — correlación proceso↔red por PID
  • Correlación automática hallazgo↔línea temporal (related_events)
  • Remediación guiada para las tres reglas que requieren criterio
  • 282 pruebas con 92% de cobertura

Las búsquedas de hash en VirusTotal y la exportación de IOC a MISP se descartaron de esta versión. VirusTotal solo responde para hashes conocidos — el caso que rkhunter ya cubre, y lo opuesto a la brecha de técnicas novedosas que ubuntils apunta — y ambas características habrían puesto una llamada de red dentro de una herramienta cuyo valor se basa en no hacer ninguna. ubuntils en sí mismo sigue sin hacer llamadas de red (ver la integración con Wazuh para la única forma opcional de que los hallazgos salgan del host, vía un agente local).

v2.0.0 — división offline collect/analyze

  • ubuntils collect — adquiere un bundle a prueba de manipulación (manifest.json + archivos/comandos con hash) de un host en vivo, sin detección
  • ubuntils analyze (BUNDLE | --root PATH) — ejecuta la misma canalización de detección/línea temporal que scan contra un bundle o una imagen montada, sin requerir root
  • bundle_integrity (live/ok/mismatch) expuesto en scan_metadata
  • Brechas de cobertura de detección documentadas en modo offline (PROCESS_MASQUERADE, PROCESS_SUSPICIOUS_CONNECTION, y cobertura reducida para rutas glob de cron/sudoers/SSH y ExecStart de temporizadores systemd)
  • Detección fiable: puntuación de confianza (confidence/confidence_band/signals), supresión con --baseline, reemplazando heurísticas basadas solo en mtime en SSH_UNAUTHORIZED_KEY/SHELL_RC_MODIFICATION con señales de ctime + contenido, y una línea temporal offline real tanto para analyze BUNDLE como para analyze --root
  • Paquete de cobertura: PACKAGE_TAMPERED, IMMUTABLE_FLAG_SET, PAM_BACKDOOR, KERNEL_MODULE_SUSPICIOUS, SETUID_INVENTORY (vía PackageCollector, PamCollector, KernelCollector; todos solo de marcado por diseño)
  • 400 pruebas con 93.79% de cobertura

v2.1.0 — reenvío a SIEM

  • Hallazgos de ubuntils scan en vivo reenviados a un agente local de Wazuh como JSONL, autodetectado (sin flag requerido)
  • Decodificador/reglas de ejemplo de Wazuh y fragmento <localfile> de ossec.conf (examples/wazuh/)
  • Reenvío intencionalmente limitado solo a scan en vivo — nunca se activa durante analyze offline, ya que un bundle o imagen describe un host diferente al que ejecuta el agente
  • --no-wazuh para excluir un escaneo del reenvío

v2.1.0 — endurecimiento (auditoría completa del código base)

  • Seguridad: la re-ejecución de sudo ya no reenvía el PATH del llamador, y los comandos se resuelven en una ruta segura fija; las ediciones de sudoers se verifican con visudo antes de tocar el archivo; escrituras de remediación atómicas; salida de informes/bundles segura frente a enlaces simbólicos; bundles extraídos eliminados después de analyze
  • Cobertura de detección: /etc/ld.so.preload analizado, entradas de cron @reboot/@daily y scripts de /etc/cron.{hourly,daily,weekly,monthly}, unidades .service de systemd y binarios ExecStart no propiedad de root, reglas sudoers de %group y #include/@includedir, cada elemento de una lista LD_PRELOAD
  • Nueva regla USER_EMPTY_PASSWORD (cuenta de inicio de sesión sin contraseña)
  • Menos falsos positivos: comprobaciones de rutas delimitadas por separadores, setuid vs setgid diferenciados, demonios de snap//usr/lib tratados como estándar, KERNEL_MODULE_SUSPICIOUS degradado a LOW, un hallazgo NSS por módulo
  • Informes honestos: reglas fallidas y recolectores degradados registrados en scan_metadata y en la TUI; un fallo de línea temporal ya no descarta hallazgos; bundles manipulados advierten y salen con código 3; año/zona horaria de syslog manejados correctamente
  • Remediación más segura: puerta --min-confidence (predeterminado 40), resultados mostrados en la TUI después de scan --remediate
  • 444 pruebas con 94.29% de cobertura

v3.0.0 / v4.0.0 (exploratorio)

  • Panel web para triaje multi-host
  • Soporte para macOS

Contribuir

Las contribuciones más útiles en este momento son nuevas reglas de detección (añadidas como funciones independientes en detectors/rules.py con una prueba correspondiente), recolectores adicionales para tipos de artefactos aún no cubiertos, módulos de remediación para SUSPICIOUS_SYSTEMD_TIMER y SHELL_RC_MODIFICATION (ambos actualmente solo de marcado por diseño, pero pueden existir rutas de auto-remediación seguras), casos de prueba para casos límite en configuraciones específicas de Ubuntu, y mejoras en la documentación.

Abre un issue antes de comenzar una contribución grande para evitar trabajo duplicado.


Licencia

MIT


Autor

Creado por Asmit — BTech en Ciencias de la Computación, PES University, Bengaluru. La herramienta surgió de la frustración con lo mucho que tarda el triaje manual de Ubuntu en comparación con lo que un script bien delimitado puede automatizar.

Descargar herramienta
SHELL_RC_MODIFICATIONLOWNoArchivos de inicio de shell (bashrc, profile, zshrc, etc.) modificados en las últimas 48 horas para cualquier usuario con shell de inicio de sesión
PACKAGE_TAMPEREDHIGHNoArchivos de paquetes propiedad del sistema modificados, ausentes, o cuyo contenido/modo/tamaño no coincide con el manifiesto del paquete (mediante dpkg --verify)
IMMUTABLE_FLAG_SETMEDIUMNoIndicadores inmutable (i) o solo anexar (a) establecidos en archivos sensibles como /etc/passwd, /etc/sudoers o /etc/pam.d/* (detectado mediante lsattr)
PAM_BACKDOORHIGHNoUna línea literal pam_permit.so en cualquier archivo /etc/pam.d/*, o un módulo NSS en /etc/nsswitch.conf fuera de una lista de permitidos (files/sss/ldap/winbind/...)
KERNEL_MODULE_SUSPICIOUSLOWNoMódulos del kernel cargados fuera de una lista de permitidos de módulos integrados comunes — nota: los hosts con mucho hardware (GPU, tarjetas Wi-Fi, controladores propietarios) verán falsos positivos; añada los módulos esperados mediante --config
SETUID_INVENTORYLOWNoBinarios setuid o setgid inesperados fuera de un conjunto de referencia conocido (los dos bits se comprueban y notifican por separado)