Entrada

Bandit: nivel 9 → 10

Un fichero binario lleno de caracteres ilegibles y una contraseña escondida tras varios signos de igual. Usamos strings para sacar el texto legible y grep para encontrarla.

Bandit: nivel 9 → 10

En el nivel anterior el fichero data.txt era texto normal, solo que con muchas líneas repetidas. Ahora el data.txt es otra cosa: un fichero binario, lleno de bytes que no representan ningún carácter legible. La contraseña está ahí dentro, rodeada de basura. El reto es sacar a la luz solo la parte que se puede leer, y para eso existe un comando con un nombre muy descriptivo: strings.

Las contraseñas aparecen como [REDACTED], siguiendo las normas de OverTheWire.

Conexión al nivel 9

1
2
$ sshpass -p '[REDACTED]' ssh bandit9@bandit.labs.overthewire.org -p 2220
bandit9@bandit:~$ export TERM=xterm

El enunciado

Según el enunciado del nivel 10, la contraseña está en el fichero data.txt, en una de las pocas cadenas legibles del fichero, precedida por varios signos =.

1
2
bandit9@bandit:~$ ls
data.txt

El problema: cat con un fichero binario

Si probamos con cat data.txt, la terminal se llena de símbolos raros, caracteres de control y huecos. No es que el fichero esté roto: cat simplemente vuelca los bytes tal cual, y la terminal intenta pintar como caracteres cosas que nunca fueron texto.

Volcar un binario con cat puede llegar a desconfigurar la terminal (colores extraños, caracteres cambiados), porque algunos bytes se interpretan como secuencias de control. Si te pasa, el comando reset la deja como nueva.

Tampoco nos sirve ir directos con grep "=====" data.txt: cuando grep detecta que un fichero es binario, en lugar de mostrar las líneas que coinciden solo avisa de que hay coincidencias, con un mensaje del tipo binary file matches (el texto exacto depende de la versión). Necesitamos convertir el binario en texto antes de filtrar.

La solución: strings + grep

1
bandit9@bandit:~$ strings data.txt | grep "====="

strings recorre el fichero byte a byte y extrae las secuencias de caracteres imprimibles de al menos 4 caracteres seguidos (ese es el mínimo por defecto). Todo lo demás lo ignora. El resultado es una lista de “trozos de texto” sacados del binario, uno por línea, que ya podemos pasar por la tubería a grep como en los niveles anteriores.

grep "=====" se queda con las cadenas que contienen al menos cinco signos de igual seguidos. Con esto ya vemos unas pocas líneas que empiezan por =, y la contraseña está en la última de ellas.

¿Por qué cinco = y no uno solo? Porque entre tanta basura binaria es fácil que alguna cadena tenga un = suelto por casualidad. Exigir varios seguidos hace que el filtro sea mucho más preciso.

Afinando: quedarnos solo con la contraseña

1
2
bandit9@bandit:~$ strings data.txt | grep "=====" | tail -n 1 | awk '{print $2}'
[REDACTED]

Añadimos dos eslabones más a la cadena:

ParteQué hace
strings data.txtExtrae el texto legible del binario.
grep "====="Deja solo las cadenas con varios = seguidos.
tail -n 1Se queda con la última línea, que es la que lleva la contraseña.
awk '{print $2}'Separa por espacios e imprime el segundo campo: la contraseña sin los = delante.

tail es el hermano de head, que usamos en el nivel anterior: en lugar de las primeras líneas, muestra las últimas. Y awk '{print $2}' es exactamente el mismo truco del nivel 7 → 8: los signos de igual son el primer campo y la contraseña, el segundo.

tail -n 1 funciona porque, en este fichero, la contraseña es la última coincidencia. Es una solución válida, pero depende de la posición. En la tercera alternativa de abajo tienes un filtro que no depende del orden.

Otras formas

1. Comprobar qué tipo de fichero es con file

1
bandit9@bandit:~$ file data.txt

Antes de abrir un fichero que no conoces, file te dice qué es mirando su contenido, no su extensión. Que se llame .txt no garantiza que sea texto, y este nivel es la prueba. Si file no dice que es texto (ASCII text o similar), ya sabes que cat te va a mostrar basura y que toca usar strings.

2. Obligar a grep a tratar el binario como texto con -a

1
bandit9@bandit:~$ grep -a "=====" data.txt

La opción -a (text) le dice a grep que procese el fichero como si fuera texto aunque detecte que es binario. Así sí muestra las líneas que coinciden, pero con un inconveniente: como en un binario las “líneas” pueden ser larguísimas y estar llenas de bytes raros, la contraseña aparece rodeada de basura. Funciona, pero strings deja un resultado mucho más limpio.

3. Un filtro que no depende del orden

1
2
bandit9@bandit:~$ strings data.txt | grep "=====" | grep -oE '[[:alnum:]]{32}'
[REDACTED]

En lugar de quedarnos con la última línea, buscamos la forma de la contraseña: las de Bandit son 32 caracteres alfanuméricos.

  • -E activa las expresiones regulares extendidas, que permiten usar {32} sin escapar las llaves.
  • [[:alnum:]] es cualquier letra o número, y {32} exige exactamente 32 seguidos.
  • -o (only matching) hace que grep imprima solo la parte que coincide, no la línea entera. Por eso los = desaparecen sin necesidad de awk.

Mientras solo una de las líneas tenga 32 caracteres alfanuméricos seguidos, da igual dónde esté: la encuentra.

Pasar al nivel siguiente

1
2
bandit9@bandit:~$ exit
$ sshpass -p '[REDACTED]' ssh bandit10@bandit.labs.overthewire.org -p 2220

Resumen

Comando / conceptoPara qué sirve
strings ficheroExtraer las cadenas de texto legible de un binario
file ficheroSaber qué tipo de fichero es, por su contenido
tail -n 1Quedarse con la última línea
grep -aTratar un binario como texto
grep -oE 'regex'Imprimir solo la parte que coincide con una expresión regular
[[:alnum:]]{32}Exactamente 32 letras o números seguidos
resetArreglar la terminal si un binario la desconfigura
Esta entrada está licenciada bajo CC BY 4.0 por el autor.