Índice / Módulo 1 — Mentalidad y Entorno

1.7 Gestión de snapshots

En un laboratorio de hacking las cosas se rompen. Es parte del proceso. La diferencia entre perder dos horas reconfigurando una máquina y volver al estado limpio en diez segundos es haber tomado un snapshot antes de empezar. Este apartado te enseña cuándo, cómo y desde dónde hacerlo.

1.7.1 ¿Qué es un snapshot y por qué el "antes" te salva la vida?

Un snapshot es una fotografía del estado completo de un sistema en un momento determinado: el contenido del disco, el estado de la memoria RAM, la configuración de red, los procesos en ejecución. Cuando algo sale mal — y en un laboratorio de hacking algo siempre sale mal — puedes volver a ese momento exacto sin reinstalar, sin reconfigurar, sin perder el trabajo anterior.

La diferencia con un backup es fundamental. Un backup copia datos. Un snapshot congela el estado completo del sistema — incluyendo qué estaba corriendo, qué archivos estaban abiertos, en qué punto del proceso estabas. Restaurar un snapshot no es recuperar ficheros: es viajar en el tiempo.

Línea de tiempo de snapshots con puntos de restauración

Cuándo tomar un snapshot

La regla es simple: toma un snapshot antes de cualquier operación que pueda dejar el sistema en un estado difícil de revertir. En la práctica, eso significa:

  • Antes de ejecutar un exploit: especialmente uno que modifica configuraciones del sistema, crea usuarios, instala persistencia o altera archivos críticos
  • Antes de instalar herramientas o dependencias: los conflictos de paquetes en Kali pueden dejar el sistema en un estado inconsistente
  • Cuando la máquina objetivo está "limpia y funcional": acabas de configurar DVWA, todo funciona — ese es el momento de congelar el estado
  • Antes de aplicar un parche o actualización: en máquinas vulnerables intencionadamente, una actualización puede eliminar la vulnerabilidad que ibas a practicar
  • Al terminar una sesión de trabajo satisfactoria: si llevas dos horas configurando un laboratorio de AD y todo funciona, toma un snapshot antes de apagar

Cómo funciona técnicamente

Los snapshots no duplican el disco completo — eso sería prohibitivo en espacio. Usan un mecanismo llamado copy-on-write (CoW): cuando tomas el snapshot, el sistema congela el estado del disco en ese punto. A partir de ahí, cualquier escritura nueva va a un archivo diferencial (delta disk) que solo contiene los cambios respecto al snapshot. El disco original queda intacto.

El resultado es que un snapshot recién creado ocupa casi cero espacio. A medida que la máquina escribe datos, el diferencial crece. Si tomas muchos snapshots encadenados, cada uno registra solo los cambios respecto al anterior, formando una cadena:

esquema — cadena de snapshots CoW
# Cadena de snapshots encadenados
Disco base (estado original, inmutable)
    
Snapshot 1 — "instalación limpia"     # delta: ~0 MB al crearlo
    
Snapshot 2 — "DVWA configurado"       # delta: cambios desde snap1
    
Snapshot 3 — "antes del exploit"      # delta: cambios desde snap2
    
Estado actual (escrituras en curso)

# Restaurar Snapshot 2 descarta Snapshot 3 y el estado actual
# La cadena puede ramificarse si creas snapshots desde un estado anterior

El coste real

Los snapshots no son gratuitos. Hay dos penalizaciones que debes conocer:

  • Espacio en disco: acumulativo. Una cadena larga de snapshots puede crecer hasta ocupar tanto como el disco original. Elimina snapshots que ya no necesites — no los acumules indefinidamente.
  • Rendimiento de I/O: cada escritura en disco requiere primero verificar si el bloque ya fue copiado al diferencial (el mecanismo CoW). Con cadenas largas de snapshots, el rendimiento de disco puede degradarse notablemente. Para máquinas de uso intensivo, consolida los snapshots periódicamente.
⚠️
Snapshots no son backups: Si el disco físico falla, el snapshot y el disco base se pierden juntos. Los snapshots protegen contra errores de configuración y cambios no deseados; los backups protegen contra pérdida de hardware. Un laboratorio serio necesita ambos.

1.7.2 Snapshots en Docker: docker commit vs volúmenes vs checkpoint

Docker tiene una filosofía diferente a las VMs respecto a la persistencia: los contenedores son efímeros por diseño. El estado no se guarda en el contenedor sino en imágenes y volúmenes. Esto cambia cómo piensas en los "snapshots" de Docker — no hay un equivalente directo al snapshot de VirtualBox, pero hay tres mecanismos que cubren los distintos casos de uso.

docker commit — guardar el estado del filesystem

docker commit crea una nueva imagen a partir del estado actual de un contenedor en ejecución. Es la aproximación más directa al concepto de snapshot: congela el sistema de archivos del contenedor en ese momento y lo guarda como una imagen reutilizable.

bash — docker commit
# Escenario: tienes DVWA corriendo y lo has configurado a tu gusto
# Quieres guardar ese estado para no tener que reconfigurar cada vez

# Ver el contenedor en ejecución
docker ps
# CONTAINER ID   IMAGE                   NAMES
# a3f2b1c4d5e6   vulnerables/web-dvwa    dvwa

# Crear una imagen desde el estado actual del contenedor
docker commit \
    --author "laboratorio" \
    --message "DVWA configurado nivel low, base de datos inicializada" \
    dvwa \
    dvwa-configurado:v1

# Verificar que la imagen se creó
docker images dvwa-configurado
# REPOSITORY        TAG   IMAGE ID       SIZE
# dvwa-configurado  v1    b7c3d2e1f0a9   450MB

# Crear un contenedor nuevo desde la imagen guardada
docker run -d --name dvwa_restaurado -p 8080:80 dvwa-configurado:v1

# Guardar la imagen a un archivo (para moverla a otro equipo)
docker save dvwa-configurado:v1 | gzip > dvwa-configurado-v1.tar.gz

# Cargar la imagen desde el archivo
docker load -i dvwa-configurado-v1.tar.gz

# Taggear la imagen con un nombre más descriptivo
docker tag dvwa-configurado:v1 dvwa-configurado:antes-sqli
⚠️
Limitación de docker commit: Solo guarda el sistema de archivos — no el estado de los procesos en ejecución ni los datos en memoria. Si tienes un proceso con estado (como una base de datos con transacciones abiertas), el commit captura el disco pero no ese estado en vuelo. Para bases de datos, usa volúmenes o haz un dump SQL antes del commit.

Volúmenes — persistir datos entre contenedores

Los volúmenes son la forma correcta de persistir datos en Docker. Viven fuera del contenedor, en el sistema de archivos del anfitrión gestionado por Docker. Cuando el contenedor se destruye, el volumen permanece. Cuando creas un contenedor nuevo con el mismo volumen, tiene acceso a todos esos datos.

bash — volúmenes Docker
# Crear un volumen nombrado
docker volume create dvwa_datos

# Usar el volumen en un contenedor
docker run -d \
    --name dvwa \
    -p 8080:80 \
    -v dvwa_datos:/var/lib/mysql \
    vulnerables/web-dvwa

# El volumen sobrevive al contenedor
docker rm dvwa
docker volume ls          # dvwa_datos sigue aquí

# Nuevo contenedor con los mismos datos
docker run -d --name dvwa2 -p 8080:80 \
    -v dvwa_datos:/var/lib/mysql \
    vulnerables/web-dvwa

# Ver dónde vive el volumen en el anfitrión
docker volume inspect dvwa_datos
# "Mountpoint": "/var/lib/docker/volumes/dvwa_datos/_data"

# Hacer backup de un volumen
docker run --rm \
    -v dvwa_datos:/origen \
    -v $(pwd):/backup \
    alpine \
    tar czf /backup/dvwa_datos_backup.tar.gz -C /origen .

# Restaurar el backup a un volumen nuevo
docker volume create dvwa_datos_restaurado
docker run --rm \
    -v dvwa_datos_restaurado:/destino \
    -v $(pwd):/backup \
    alpine \
    tar xzf /backup/dvwa_datos_backup.tar.gz -C /destino

CRIU / checkpoint — congelar el proceso completo

CRIU (Checkpoint/Restore In Userspace) es la tecnología que permite congelar un proceso en ejecución — incluyendo su estado en memoria, sus descriptores de archivo abiertos, sus conexiones de red — y restaurarlo después exactamente donde se quedó. Es el equivalente más fiel al snapshot de VM aplicado a contenedores.

Docker tiene soporte experimental para CRIU a través del flag --checkpoint. En la práctica, para laboratorios de hacking el uso más común de esta tecnología es con docker pause / docker unpause, que suspende y reanuda los procesos del contenedor sin perder su estado:

bash — pause/unpause y checkpoint experimental
# Pausar un contenedor (congela todos sus procesos con SIGSTOP)
# El contenedor sigue "vivo" pero no consume CPU
docker pause dvwa

# Verificar que está pausado
docker ps
# STATUS: Up 2 hours (Paused)

# Reanudar
docker unpause dvwa

# ─────────────────────────────────────────────
# CHECKPOINT EXPERIMENTAL (requiere CRIU instalado)
# ─────────────────────────────────────────────

# Instalar CRIU en el anfitrión (Debian/Ubuntu)
sudo apt install -y criu

# Habilitar el plugin experimental en /etc/docker/daemon.json
# { "experimental": true }
sudo systemctl restart docker

# Crear un checkpoint del contenedor (lo congela y guarda en disco)
docker checkpoint create dvwa checkpoint_antes_exploit

# El contenedor se detiene — los datos quedan en:
# /var/lib/docker/containers/<id>/checkpoints/checkpoint_antes_exploit/

# Restaurar desde el checkpoint
docker start --checkpoint checkpoint_antes_exploit dvwa

# Listar checkpoints disponibles
docker checkpoint ls dvwa

¿Cuál usar en cada caso?

Mecanismo Qué guarda Caso de uso ideal Limitación
docker commit Sistema de archivos del contenedor Guardar una configuración personalizada para reutilizar No guarda estado en memoria ni procesos
Volúmenes Datos específicos en rutas montadas Persistir bases de datos y datos de aplicación Solo persiste los datos del volumen, no la configuración
docker pause Estado en memoria (suspendido) Pausar temporalmente sin perder estado No sobrevive a un reinicio del anfitrión
CRIU checkpoint Estado completo: memoria, ficheros, red Snapshot real de un proceso en ejecución Experimental, no funciona con todos los contenedores

1.7.3 Snapshots en VirtualBox: GUI vs VBoxManage CLI

VirtualBox tiene el sistema de snapshots más completo y accesible para laboratorios de hacking. Puedes tomar snapshots en caliente (con la máquina encendida), en frío (apagada), con o sin memoria RAM incluida, y restaurarlos en cuestión de segundos. Todo desde la GUI o desde línea de comandos con VBoxManage.

Interfaz de snapshots de VirtualBox con árbol de estados
Interfaz de snapshots de VirtualBox con árbol de estados

Desde la GUI de VirtualBox

  1. Selecciona la VM en el panel izquierdo
  2. Haz clic en el menú desplegable junto al botón de inicio → Snapshots (o usa el icono de cámara en la barra lateral derecha)
  3. Para tomar un snapshot: botón Take (icono de cámara) → escribe un nombre descriptivo y una descripción opcional → OK
  4. Para restaurar: selecciona el snapshot en el árbol → Restore → confirmar
  5. Para eliminar: selecciona el snapshot → Delete
💡
Nombre los snapshots con contexto: "Snapshot 1", "Snapshot 2" no sirve de nada cuando tienes diez. Usa nombres como "kali-limpio-herramientas-instaladas", "dvwa-antes-sqli-lab", "metasploitable-estado-inicial". El campo de descripción también es útil para apuntar qué tiene instalado en ese punto.

Desde VBoxManage CLI

La línea de comandos es imprescindible para automatizar la gestión de snapshots — scripts de laboratorio, rollback en un comando, integración con otras herramientas. VBoxManage snapshot tiene todo lo necesario.

bash — VBoxManage snapshots
## INFORMACIÓN

# Listar todas las VMs registradas
VBoxManage list vms

# Listar snapshots de una VM
VBoxManage snapshot "Kali" list
VBoxManage snapshot "Kali" list --details   # Con UUIDs y fechas

## TOMAR SNAPSHOTS

# Snapshot básico (con la VM encendida o apagada)
VBoxManage snapshot "Kali" take "herramientas-instaladas"

# Snapshot con descripción
VBoxManage snapshot "Kali" take "antes-exploit" \
    --description "Kali con metasploit actualizado, antes de atacar DVWA"

# Snapshot incluyendo la memoria RAM (más grande, permite restaurar con procesos activos)
VBoxManage snapshot "Kali" take "con-ram" --live

## RESTAURAR SNAPSHOTS

# Restaurar al snapshot más reciente
VBoxManage snapshot "Kali" restorecurrent

# Restaurar a un snapshot específico (por nombre)
VBoxManage snapshot "Kali" restore "herramientas-instaladas"

# Restaurar a un snapshot específico (por UUID — más preciso si hay nombres duplicados)
VBoxManage snapshot "Kali" restore "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

## ELIMINAR SNAPSHOTS

# Eliminar un snapshot por nombre (los cambios se fusionan con el padre)
VBoxManage snapshot "Kali" delete "snapshot-viejo"

## EDITAR METADATOS

# Cambiar el nombre o descripción de un snapshot existente
VBoxManage snapshot "Kali" edit "antes-exploit" \
    --name "antes-sqli-dvwa" \
    --description "Estado antes de practicar SQLi en DVWA nivel medium"

Flujo de trabajo recomendado para un laboratorio

bash — flujo típico de trabajo con snapshots
# 1. Configurar la máquina objetivo desde cero
#    (instalar DVWA, configurar la base de datos, ajustar nivel de seguridad)

# 2. Tomar el snapshot base — estado limpio y funcional
VBoxManage snapshot "DVWA-Lab" take "estado-inicial" \
    --description "DVWA instalado, nivel Low, DB inicializada"

# 3. Practicar el ejercicio (SQLi, XSS, lo que sea)
#    La máquina puede quedar en cualquier estado

# 4. Cuando quieras empezar de nuevo: restaurar en un comando
VBoxManage snapshot "DVWA-Lab" restore "estado-inicial"
VBoxManage startvm "DVWA-Lab" --type headless

# 5. En 30 segundos tienes la máquina exactamente como al principio

VMware Workstation (equivalente)

En VMware los snapshots funcionan igual conceptualmente. Los comandos desde línea de comandos usan vmrun:

bash — snapshots en VMware con vmrun
# Tomar snapshot (la VM puede estar encendida)
vmrun -T ws snapshot /ruta/a/VM.vmx "estado-inicial"

# Listar snapshots
vmrun -T ws listSnapshots /ruta/a/VM.vmx

# Restaurar snapshot
vmrun -T ws revertToSnapshot /ruta/a/VM.vmx "estado-inicial"

# Eliminar snapshot
vmrun -T ws deleteSnapshot /ruta/a/VM.vmx "estado-inicial"

1.7.4 Rolling-back automatizado: script de un solo comando

Tener que abrir VirtualBox, navegar al gestor de snapshots, seleccionar el snapshot correcto y confirmar la restauración es lento cuando lo haces decenas de veces en una sesión de laboratorio. La solución es un script que hace todo eso en un comando desde el terminal del anfitrión.

Script de reset básico

El script más simple posible: para la VM, restaura el snapshot de estado inicial y la vuelve a arrancar.

bash — reset_vm.sh (script básico)
#!/bin/bash
# reset_vm.sh — restaura una VM al snapshot de estado inicial
# Uso: ./reset_vm.sh [nombre_vm] [nombre_snapshot]

VM_NAME="${1:-DVWA-Lab}"          # Nombre por defecto si no se pasa argumento
SNAPSHOT="${2:-estado-inicial}"

echo "[*] Reseteando $VM_NAME al snapshot '$SNAPSHOT'..."

# Apagar la VM si está encendida (forzado)
VBoxManage controlvm "$VM_NAME" poweroff 2>/dev/null
sleep 2

# Restaurar el snapshot
VBoxManage snapshot "$VM_NAME" restore "$SNAPSHOT"
if [ $? -ne 0 ]; then
    echo "[!] Error: no se encontró el snapshot '$SNAPSHOT'"
    exit 1
fi

# Arrancar en modo headless (sin ventana)
VBoxManage startvm "$VM_NAME" --type headless

echo "[✓] $VM_NAME restaurada y arrancando en segundo plano"
bash — uso del script
# Dar permisos de ejecución
chmod +x reset_vm.sh

# Uso con los valores por defecto (DVWA-Lab, estado-inicial)
./reset_vm.sh

# Uso especificando VM y snapshot
./reset_vm.sh "Metasploitable3" "limpio"

# Crear alias en .bashrc para llamarlo desde cualquier sitio
echo "alias reset-dvwa='~/scripts/reset_vm.sh DVWA-Lab estado-inicial'" >> ~/.bashrc
source ~/.bashrc

# Ahora basta con escribir:
reset-dvwa

Script de reset para laboratorio completo

Cuando el laboratorio tiene varias máquinas (atacante + objetivo + router), necesitas resetearlas todas coordinadamente. Este script lo hace en paralelo:

bash — reset_lab.sh (laboratorio multi-VM)
#!/bin/bash
# reset_lab.sh — resetea todas las VMs del laboratorio en paralelo

# Definir las VMs y sus snapshots de estado inicial
# Formato: "NOMBRE_VM:SNAPSHOT"
LAB_VMS=(
    "Kali:herramientas-ok"
    "DVWA-Lab:estado-inicial"
    "Router-VM:configurado"
)

reset_vm() {
    local vm_name="${1%%:*}"      # Todo antes del ":"
    local snapshot="${1##*:}"     # Todo después del ":"

    echo "[*] Reseteando $vm_name → $snapshot"

    VBoxManage controlvm "$vm_name" poweroff 2>/dev/null
    sleep 1
    VBoxManage snapshot "$vm_name" restore "$snapshot" 2>/dev/null
    VBoxManage startvm "$vm_name" --type headless 2>/dev/null

    echo "[✓] $vm_name lista"
}

echo "[*] Iniciando reset del laboratorio..."

# Lanzar los resets en paralelo (& al final de cada llamada)
for vm in "${LAB_VMS[@]}"; do
    reset_vm "$vm" &
done

# Esperar a que todos los procesos en paralelo terminen
wait

echo "[✓] Laboratorio reseteado. Espera 30s para que las VMs arranquen."

Reset equivalente para laboratorios Docker

En Docker el concepto de "reset al estado inicial" es más simple: destruyes los contenedores y los vuelves a crear desde la imagen original. Si usas Compose, es un solo comando:

bash — reset de laboratorio Docker
# Reset completo: destruir todo y recrear
docker compose down -v && docker compose up -d

# Reset conservando los volúmenes (datos persistentes)
docker compose down && docker compose up -d

# Script de reset para Docker más robusto
#!/bin/bash
# reset_docker_lab.sh

LAB_DIR="${1:-$(pwd)}"   # Directorio del compose, por defecto el actual

echo "[*] Reseteando laboratorio Docker en $LAB_DIR..."
cd "$LAB_DIR" || exit 1

# Parar y eliminar contenedores y redes (conservar volúmenes)
docker compose down --remove-orphans

# Levantar de nuevo desde las imágenes originales
docker compose up -d

echo "[✓] Laboratorio Docker listo"
docker compose ps

Configurar aliases permanentes

La forma más cómoda de usar estos scripts es como aliases en tu shell. Añade esto a tu ~/.bashrc o ~/.zshrc:

bash — aliases de laboratorio en .bashrc / .zshrc
# Añadir al final de ~/.bashrc o ~/.zshrc

# Reset de VMs individuales
alias reset-kali='VBoxManage snapshot "Kali" restore "herramientas-ok" && VBoxManage startvm "Kali" --type headless'
alias reset-dvwa='VBoxManage snapshot "DVWA-Lab" restore "estado-inicial" && VBoxManage startvm "DVWA-Lab" --type headless'

# Reset del laboratorio completo
alias reset-lab='~/scripts/reset_lab.sh'

# Reset del laboratorio Docker
alias reset-docker='cd ~/labs/docker && docker compose down && docker compose up -d'

# Ver estado de todas las VMs
alias lab-status='VBoxManage list runningvms && docker ps'

# Apagar todo el laboratorio de golpe
alias lab-off='VBoxManage list runningvms | grep -oP "(?<=\")[^\"]*(?=\")" | \
     xargs -I{} VBoxManage controlvm "{}" savestate && docker compose -f ~/labs/docker/docker-compose.yml down'

# Activar los cambios sin cerrar el terminal
source ~/.bashrc
💡
Guardar los scripts en un repositorio: Pon tus scripts de laboratorio en un repositorio git privado. Así tienes control de versiones sobre la configuración, puedes recuperarlos si reinstallas el sistema, y puedes compartirlos con otros si trabajas en equipo. Una carpeta ~/labs/scripts/ versionada con git es parte de un laboratorio bien construido.