OverTheWire Bandit: Apuntes de los Niveles 0–12
Un walkthrough amigable de OverTheWire Bandit, niveles 0–12 — SSH, archivos ocultos, find, stderr, codificaciones y un hexdump que no deja de abrirse. Contraseñas omitidas, según las reglas.
Aviso de spoiler: Este post recorre los niveles 0–12 de OverTheWire Bandit. Si estás jugando, intenta cada nivel antes de leer. Siguiendo las reglas de OverTheWire para creadores de contenido, aquí no se publica ninguna contraseña — todas las credenciales están omitidas. Bandit es gratuito; si te ayuda, considera donar a OverTheWire.
Bandit es el wargame para principiantes de OverTheWire y el primero que recomiendo a cualquiera que quiera sentirse cómodo en la línea de comandos de Linux. No hay interfaz gráfica, no hay framework de explotación y no hay adivinanzas: te conectas por SSH, resuelves un pequeño rompecabezas del sistema de archivos y usas la contraseña que encuentras para entrar al siguiente nivel.
Pasé por los niveles 0–12 durante algunas noches. Estos son mis apuntes — ordenados, sin los callejones sin salida y con los comandos que realmente usé. El objetivo no es memorizar una lista de respuestas. Es mostrar el ritmo: mira lo que tienes, pregunta qué es y elige la herramienta más pequeña que responde a la pregunta.
Antes de Empezar
Algunas notas prácticas:
- El host del juego es
bandit.labs.overthewire.orgy el puerto SSH es2220, no el22por defecto. - Tus credenciales iniciales están en la página del nivel 0 de Bandit. No voy a repetir la contraseña aquí.
- La contraseña de cada nivel te permite entrar al siguiente. El nombre de usuario cambia:
bandit0,bandit1,bandit2, y así sucesivamente. - Una terminal de Linux/macOS es suficiente. En Windows, usa WSL.
- Lee los mensajes de error. Normalmente dicen exactamente qué salió mal.
El comando de inicio de sesión es así:
ssh [email protected] -p 2220
La primera vez que te conectas, SSH pregunta si confías en la huella digital del host:
The authenticity of host '[bandit.labs.overthewire.org]:2220' can't be established.
ED25519 key fingerprint is SHA256:...
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Escribe yes si la huella coincide con lo que esperas (o si aceptas el riesgo para un host de juego) y pega la contraseña de la página del nivel. La contraseña no se muestra en pantalla — eso es normal.
Cuando termines, exit cierra la sesión. Después entra como el siguiente usuario con la contraseña que encontraste.
Nivel 0 — Entra y Lee el README
Una vez dentro, mira a tu alrededor:
ls
Hay un único archivo llamado readme. Léelo:
cat readme
El archivo explica las reglas y termina con la contraseña de bandit1. La omití aquí:
The password you are looking for is: [redacted]
Ese es el ciclo completo. Sal y vuelve a entrar como bandit1 con esa contraseña.
Nivel 1 — Un Archivo Llamado -
El siguiente nivel dice que la contraseña está en un archivo llamado -. Si intentas lo obvio, el shell parece colgarse:
cat -
Eso pasa porque muchas herramientas Unix tratan un - solitario como "lee de la entrada estándar", no como "lee un archivo llamado -". Necesitas dejarlo inequívoco pasando una ruta:
ls -l
cat ./-
El prefijo ./ dice "la entrada llamada - en el directorio actual". $PWD/- también funciona. Yo también comprobé qué era el archivo antes de leerlo:
du ./-
file ./-
file informa que es texto ASCII, lo cual es buena señal. Después cat imprime la siguiente contraseña, otra vez omitida.
Nivel 2 — Espacios en el Nombre del Archivo
Esta vez el archivo tiene espacios en el nombre, además de guiones al principio:
ls
cat ./"--spaces in this filename--"
Las comillas mantienen el nombre completo como un solo argumento. Sin ellas, el shell divide el nombre en varios argumentos y cat se queja. El autocompletado con Tab ayuda mucho aquí: escribe cat ./--sp y pulsa Tab; el shell completa el nombre y escapa los espacios por ti.
Nivel 3 — Archivos Ocultos
ls muestra un directorio inhere, pero dentro parece no haber nada:
cd inhere
ls
Nada. El archivo está oculto, lo que en Unix significa simplemente que su nombre empieza con un punto. Pídele a ls que incluya las entradas ocultas:
ls -a
Ahora ves ...Hiding-From-You junto con los habituales . y ... La forma larga confirma que es un archivo regular:
ls -la
cat ...Hiding-From-You
Los puntos iniciales forman parte del nombre; no significan "subir un directorio" a menos que el nombre sea exactamente . o ...
Nivel 4 — El Archivo Legible por Humanos
El directorio inhere contiene diez archivos llamados -file00 a -file09. El nivel dice que solo uno es legible por humanos. Antes de volcar todos en la terminal, pregúntale al sistema qué son:
file ./-file*
file identifica el tipo de cada uno. Exactamente uno aparece como texto ASCII; los demás son datos. Lee ese:
cat ./-file07
(La respuesta habitual es -file07; usa el archivo que file indique como texto ASCII.)
Si haces lo que yo hice primero y ejecutas cat ./-file*, obtendrás una pantalla llena de basura binaria y quizá una terminal estropeada. La solución es reset, o simplemente cerrar la sesión y reconectarte. file es la primera jugada más inteligente.
Nivel 5 — Buscar por Tamaño
Ahora la contraseña está en algún lugar dentro de inhere, en un archivo legible por humanos, de exactamente 1033 bytes y sin permiso de ejecución. Hay veinte directorios maybehereNN, así que entrar en todos es una pérdida de tiempo.
find puede filtrar por todo eso:
find . -type f -size 1033c ! -executable
Una decodificación rápida:
-type fsignifica solo archivos regulares.-size 1033csignifica exactamente 1033 bytes; el sufijoces de bytes.! -executableexcluye archivos con cualquier bit de ejecución activo.
Mi primera pasada usó solo find . -size 1033c, que encontró un único resultado — pero añadir las otras propiedades hace que el comando diga exactamente lo que quieres. Cuando tengas la ruta, confírmala y lee:
file ./maybehere07/.file2
cat ./maybehere07/.file2
Nivel 6 — Todo el Sistema de Archivos y una Avalancha de Errores
Ahora el archivo puede estar en cualquier lugar del servidor. El nivel da tres propiedades: pertenece al usuario bandit7, pertenece al grupo bandit6 y tiene 33 bytes. Busca desde la raíz:
find / -type f -size 33c -user bandit7 -group bandit6
El resultado es una pared de mensajes Permission denied. Es lo esperado: como bandit6, no puedes leer todos los directorios del sistema. Lo importante es a dónde van esos mensajes. Se escriben en la salida de error estándar (descriptor de archivo 2), mientras que el resultado útil va a la salida estándar (descriptor de archivo 1).
Puedes tirar los errores a la basura:
find / -type f -size 33c -user bandit7 -group bandit6 2>/dev/null
Desglosando la línea:
2>redirige el descriptor de archivo 2 (stderr)./dev/nulles un dispositivo especial que descarta todo lo que recibe.- El resultado ahora queda legible:
./var/lib/dpkg/info/bandit7.password.
Si quieres mantener otros errores visibles y ocultar solo los de permisos, une stderr con stdout y filtra:
find / -type f -size 33c -user bandit7 -group bandit6 2>&1 | grep -v 'Permission denied'
2>&1 significa "manda stderr al mismo lugar que stdout", así que grep puede ver ambos flujos. grep -v invierte la coincidencia y descarta las líneas que no quieres. Lee el archivo:
cat ./var/lib/dpkg/info/bandit7.password
Nivel 7 — Grep en la Millonésima Palabra
data.txt tiene unos 4 MB, con una palabra por línea seguida de un valor. La contraseña está junto a la palabra millionth. No hay razón para leerlo todo:
grep "millionth" data.txt
grep imprime la línea coincidente, y el valor después del tabulador es la siguiente contraseña. En mis apuntes usé cat data.txt | grep "millionth"; funciona, pero inicia un proceso extra sin motivo. grep puede leer el archivo directamente.
Nivel 8 — La Línea que Aparece Una Sola Vez
data.txt está lleno de cadenas aleatorias repetidas. La contraseña es la única línea que aparece exactamente una vez. El comando uniq puede encontrar líneas únicas:
sort data.txt | uniq -u
El sort no es opcional. uniq solo compara líneas adyacentes, así que los duplicados que están lejos son invisibles para él. Ordenar acerca las líneas idénticas, y uniq -u imprime solo las líneas que aparecen una vez.
Una distinción útil: sort -u elimina duplicados e imprime cada línea restante una vez. sort | uniq -u imprime solo las líneas que no tenían ningún duplicado. Son preguntas diferentes.
Nivel 9 — Strings en un Archivo Binario
file data.txt dice que esto es data, no texto. cat volcaría ruido binario. El comando strings extrae secuencias de caracteres imprimibles de un archivo binario, y el nivel dice que la contraseña es una de las pocas cadenas legibles, precedida por varios caracteres =:
strings data.txt | grep "="
La salida incluye líneas como ========== password y la propia línea de la contraseña. grep "=" basta para reducir la búsqueda; los signos de igual forman parte de la pista, no son decoración.
Nivel 10 — Base64
data.txt es texto ASCII, pero está codificado. file no dice qué codificación es; el nivel sí. Base64 es una forma común de representar datos binarios como texto, y es codificación, no cifrado:
base64 -d data.txt
La opción -d decodifica. La salida es una frase legible que termina en la siguiente contraseña. Si ves una cadena que termina en = o == y usa solo letras, números, + y /, base64 es una buena apuesta.
Nivel 11 — ROT13
Todas las letras de este archivo fueron rotadas 13 posiciones. ROT13 es su propio inverso: aplicarlo dos veces devuelve el original. El comando tr mapea un conjunto de caracteres a otro:
tr 'A-Za-z' 'N-ZA-Mn-za-m' < data.txt
El mapeo es A → N, B → O, y así sucesivamente, dando la vuelta en Z; las minúsculas funcionan igual. Originalmente escribí cat data.txt | tr ..., que también funciona. La redirección de entrada (<) es más limpia porque tr no necesita un argumento de archivo.
Nivel 12 — El Hexdump que Sigue Desplegándose
Este es el nivel que parece intimidante y es, en su mayor parte, paciencia. data.txt es un hexdump de un archivo que fue comprimido varias veces. Tu trabajo es revertir el hexdump y luego preguntarle a file qué es el resultado, descomprimiéndolo con la herramienta correspondiente.
Primero, crea un directorio de trabajo en /tmp con un nombre difícil de adivinar y copia los datos allí:
WORK=$(mktemp -d)
cp ~/data.txt "$WORK/"
cd "$WORK"
mktemp -d crea un directorio único e imprime su nombre. La variable WORK lo guarda para que puedas limpiarlo después. Ahora revierte el hexdump:
xxd -r data.txt data1
file data1
xxd -r convierte el hexdump de vuelta en binario. file dice que son datos gzip, así que renómbralo con la extensión .gz y descomprime:
mv data1 data.gz
gunzip data.gz
file data
gunzip elimina el archivo .gz y escribe data. file ahora dice bzip2. Repite el mismo patrón: combina la herramienta con el tipo.
mv data data.bz2
bzip2 -d data.bz2
file data
Ahora es gzip otra vez:
mv data data.gz
gunzip data.gz
file data
Esta vez es un archivo tar POSIX:
mv data data.tar
tar xf data.tar
file *
tar xf extrae el archivo; file * muestra qué salió. Es data5.bin, y es otro archivo tar:
mv data5.bin data5.tar
tar xf data5.tar
file *
Ahora data6.bin es bzip2:
mv data6.bin data6.bz2
bzip2 -d data6.bz2
file data6.bin
Vuelve como un archivo tar, así que extráelo:
mv data6.bin data6.tar
tar xf data6.tar
file *
data8.bin es gzip. Una ronda más:
mv data8.bin data8.gz
gunzip data8.gz
file data8.bin
cat data8.bin
Esta vez file dice texto ASCII, y cat imprime la frase con la contraseña. Omití el valor:
The password is [redacted]
Los nombres exactos de los archivos pueden variar un poco entre ejecuciones, pero el ritmo no cambia: file → elige gunzip, bzip2 -d o tar xf → renombra si la herramienta exige una extensión → repite. El comando file es el mapa; las extensiones son solo pistas.
Dos notas prácticas:
gzipse niega a descomprimir un archivo sin el sufijo.gz, a menos que le digas lo contrario. Renombrar es la solución más simple.gunzipes solo otro nombre paragzip -d.- Cuando termines, limpia lo que creaste, como piden las reglas de OverTheWire:
cd ~ && rm -r "$WORK".
Nivel 13 — Continuará...
El nivel 13 cambia el patrón. En lugar de darte una contraseña, te da una clave SSH privada que puede entrar como bandit14, y la siguiente contraseña vive en un archivo que solo bandit14 puede leer. Eso significa permisos de la clave, ssh -i y leer los mensajes de error con atención — el archivo de pistas del nivel existe por una razón.
Todavía no escribí esa parte. Sí, este post termina en un cliffhanger. El siguiente empieza en el nivel 13.
Lo Que Me Llevo
Ninguno de estos niveles exigió un exploit sofisticado. Exigieron saber qué herramienta pequeña responde a la pregunta:
ls -apara nombres ocultos.fileantes decat, sobre todo cuando el "archivo" puede no ser texto.findpor propiedades, no solo por nombres.2>y2>&1para separar la salida útil del ruido.grep,sort,uniq,strings,base64ytrpara filtrar y decodificar.xxd -rmásfilepara pelar capas de compresión.
La meta-habilidad es la misma que importa en el trabajo de seguridad: observa, formula una pequeña hipótesis, pruébala y lee el error cuando falla. Bandit es un lugar seguro para practicar ese ciclo.
Gracias a la comunidad de OverTheWire por mantener Bandit gratuito y abierto. Si estás jugando, usa las reglas y las páginas de los niveles, y no publiques credenciales — por eso todas las contraseñas de arriba están omitidas.
Buen hacking. Nivel 13 en la próxima.