Dentro de mi roadmap de 26 semanas para especializarme en ciberseguridad ofensiva, la primera parada fue OverTheWire Bandit — un wargame gratuito pensado para aprender los fundamentos de la línea de comandos de Linux resolviendo niveles, cada uno con una contraseña escondida que te da acceso al siguiente.
Qué es Bandit y cómo se juega
Bandit se juega por SSH: te conectas al nivel en el que estás con la contraseña que sacaste del nivel anterior, y dentro de ese nivel tienes que encontrar la contraseña del siguiente, normalmente escondida en un archivo, una carpeta, o el resultado de un comando concreto. Se accede así:
ssh banditN@bandit.labs.overthewire.org -p 2220
donde N es el número de nivel en el que estás. La web oficial es overthewire.org/wargames/bandit/.
Por qué Bandit es un buen punto de partida
- Es gratis y no requiere instalar nada — solo necesitas un terminal con SSH, que ya viene en Linux y macOS (y en Windows con WSL o PowerShell).
- No hay nada que romper — es un entorno controlado y pensado para eso, así que no hay riesgo legal ni técnico.
- Enseña por necesidad, no por temario — no te dan una lección sobre
grep; te ponen un problema que solo se resuelve congrep, y lo buscas tú.
Consejo antes de empezar: documenta desde el nivel 0
Un error que se paga caro más adelante: apunta cada contraseña según la consigues, en un archivo de notas propio. Los niveles no guardan progreso — si pierdes la contraseña del nivel 8, no puedes entrar, y toca rehacer los niveles anteriores para recuperarla. Un simple archivo de texto con el formato bandit8: contraseña te ahorra ese disgusto.
Los primeros niveles, de un vistazo
| Nivel | Qué hay que hacer | Comando clave |
|---|---|---|
| 0 → 1 | Leer un archivo llamado readme | cat readme |
| 1 → 2 | Leer un archivo llamado - | cat ./- |
| 2 → 3 | Leer un archivo con espacios y guiones en el nombre | cat -- "--spaces in this filename--" |
| 3 → 4 | Encontrar un archivo oculto dentro de un directorio | ls -a |
Fíjate en el patrón: los tres primeros niveles usan el mismo comando (cat). Lo que cambia no es la herramienta, sino el obstáculo — y ahí está la enseñanza real.
El primer obstáculo real: un nombre de archivo con guiones
Los primeros niveles son sencillos (localizar un archivo, leer su contenido con cat), pero en el salto del nivel 2 al 3 me encontré con un archivo llamado literalmente --spaces in this filename--. Intenté lo obvio:
cat --spaces in this filename--
Y no funcionó — porque no es un problema de espacios, es un problema de los guiones al principio. Al principio entendí el concepto al revés: pensé que el guion inicial le decía al comando “esto es un nombre de archivo, no una acción”. Es justo lo contrario: cuando un comando ve algo que empieza por guion, lo interpreta como una opción (un flag), no como un nombre de archivo — por eso cat intentaba procesar una opción llamada --spaces, que no existe, en vez de abrir el archivo.
La solución tiene dos formas, y ambas resuelven el mismo problema desde ángulos distintos:
cat -- "--spaces in this filename--"
El -- le dice al comando “a partir de aquí, todo lo que venga es un argumento normal, deja de interpretar guiones como opciones”. La otra forma habitual es anteponer la ruta:
cat ./"--spaces in this filename--"
Aquí, como el nombre ya no empieza literalmente por guion (empieza por ./, que significa “en el directorio actual”), el comando nunca llega a confundirlo con una opción.
Errores típicos con nombres de archivo “raros”, de un vistazo
| Situación | Por qué falla | Cómo se resuelve |
|---|---|---|
Archivo empieza por - | El comando lo interpreta como opción/flag | -- antes del nombre, o anteponer ./ |
| Archivo con espacios sin comillas | La shell lo trata como varios argumentos distintos | Comillas alrededor del nombre completo |
Archivo con * o ? en el nombre | La shell los expande como comodines antes de pasarlos | Comillas simples '...' |
Archivo con $ en el nombre | La shell lo interpreta como una variable | Comillas simples '...' o escapar con \$ |
Archivo oculto (empieza por .) | ls normal no lo muestra | ls -a |
Comillas simples vs comillas dobles
Un detalle que conviene aprender pronto, porque no son intercambiables:
- Comillas dobles
"..."— protegen espacios, pero siguen interpretando variables ($VAR) y algunos caracteres especiales. - Comillas simples
'...'— protegen absolutamente todo; lo que hay dentro se toma literal.
NOMBRE="Antonio"
echo "Hola $NOMBRE" # imprime: Hola Antonio
echo 'Hola $NOMBRE' # imprime: Hola $NOMBRE
Por qué esto no es solo una curiosidad de Bandit
Lo que en su momento traté como un obstáculo puntual resultó ser el primer ejemplo real de una idea que vas a encontrar una y otra vez en ciberseguridad ofensiva: la frontera entre “esto es un dato” y “esto es una instrucción” es exactamente donde se rompen la mayoría de vulnerabilidades.
Un nombre de archivo que un comando confunde con un flag es una versión diminuta e inofensiva del mismo problema de fondo que hace posible ataques mucho más serios:
| Contexto | Qué debería ser un dato | Qué acaba interpretándose como instrucción |
|---|---|---|
| Línea de comandos | Un nombre de archivo | Una opción del comando (--spaces) |
| Base de datos | Lo que el usuario escribe en un formulario | Parte de la consulta SQL (inyección SQL) |
| Navegador | Un comentario en una web | Código JavaScript que se ejecuta (XSS) |
| Sistema operativo | Un parámetro de una aplicación | Un comando del sistema (inyección de comandos) |
No hace falta entender SQL ni JavaScript todavía para quedarse con la idea: desconfiar siempre de dónde termina el dato y empieza la instrucción es un hábito mental que vale para la línea de comandos, para una base de datos, y para casi cualquier sistema que procese algo que tú (o un atacante) le entrega como entrada.
Por eso Bandit empieza donde empieza. No te está enseñando a leer archivos con nombres raros — te está metiendo en la cabeza, con un ejemplo mínimo y sin consecuencias, el patrón mental que sostiene buena parte de la seguridad ofensiva.
Cómo aprovechar Bandit de verdad (y no solo pasar niveles)
Una tentación que conviene evitar: buscar la solución en Google en cuanto te atascas, copiar el comando, y pasar al siguiente nivel. Así se avanza rápido y no se aprende nada. Lo que a mí me está funcionando:
- Intentar el nivel al menos 15-20 minutos antes de buscar ayuda.
- Cuando encuentro la solución, no seguir hasta entender por qué funciona — si no puedo explicar el comando con mis palabras, todavía no lo sé.
- Anotar el concepto, no solo el comando — “cat —” no sirve de nada dentro de seis meses; “los guiones iniciales se interpretan como flags” sí.
Pon a prueba lo que has entendido
En Linux, un archivo se llama '--spaces in this filename--'. ¿Por qué falla 'cat --spaces...' directamente?
Resumen rápido
- Bandit se juega por SSH, resolviendo niveles para conseguir la contraseña del siguiente. Apunta cada contraseña desde el primer nivel.
- Un nombre de archivo que empieza por guion se interpreta como una opción del comando — se soluciona con
--antes del nombre, o anteponiendo./. - Las comillas simples protegen literalmente todo; las dobles siguen interpretando variables.
- El patrón de fondo (confundir dato con instrucción) no es exclusivo de la línea de comandos: es la misma idea que sostiene la inyección SQL, el XSS y la inyección de comandos, solo que a mayor escala.
Sigue con la serie: el siguiente obstáculo real de Bandit llega un par de niveles después, cuando ya no basta con leer un archivo — hay que encontrarlo primero entre varios que parecen iguales. Lo ves en Bandit nivel 4 a 5: cómo encontrar el único archivo legible entre varios con file.