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.
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:
# 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.
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.
# 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
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.
# 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:
# 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.
Desde la GUI de VirtualBox
- Selecciona la VM en el panel izquierdo
- 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)
- Para tomar un snapshot: botón Take (icono de cámara) → escribe un nombre descriptivo y una descripción opcional → OK
- Para restaurar: selecciona el snapshot en el árbol → Restore → confirmar
- Para eliminar: selecciona el snapshot → Delete
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.
## 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
# 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:
# 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.
#!/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"
# 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:
#!/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:
# 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:
# 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
~/labs/scripts/ versionada con git es parte de un laboratorio bien construido.