Bandit: nivel 4 → 5
Diez ficheros y solo uno contiene texto legible. Usamos find, file y xargs para encontrarlo sin abrirlos uno a uno.
Aquí empieza lo interesante: ya no basta con abrir un fichero, hay que encontrar el bueno entre varios. Podríamos abrirlos uno a uno, pero la gracia es que lo haga la terminal por nosotros. Para eso combinamos tres herramientas que vas a usar muchísimo: find, file y xargs.
Las contraseñas aparecen como
[REDACTED], siguiendo las normas de OverTheWire.
Conexión al nivel 4
1
2
$ sshpass -p '[REDACTED]' ssh bandit4@bandit.labs.overthewire.org -p 2220
bandit4@bandit:~$ export TERM=xterm
El enunciado
La página del nivel 5 dice que la contraseña está en el único fichero human-readable del directorio inhere:
1
2
3
4
5
bandit4@bandit:~$ ls
inhere
bandit4@bandit:~$ cd inhere
bandit4@bandit:~/inhere$ ls
-file00 -file01 -file02 -file03 -file04 -file05 -file06 -file07 -file08 -file09
Diez ficheros, y todos empiezan por guion, así que ya sabemos desde el nivel 1 → 2 que habrá que tener cuidado con ellos.
Ojo con human-readable. No significa “con permisos de lectura”, sino “que contiene texto que una persona puede leer”. Los otros nueve ficheros tienen datos binarios: si los abres con
catverás caracteres raros. Entender bien el enunciado es la mitad del nivel.
La pregunta: ¿cómo lo encuentro sin abrirlos uno a uno?
Abrir diez ficheros a mano es viable, pero no escala: si fueran mil, no lo harías así. Además, hacer cat de un fichero binario puede dejar la terminal llena de basura. La propia página del nivel avisa: si se te descontrola la terminal, prueba el comando reset.
Lo que necesitamos es una herramienta que nos diga qué tipo de contenido tiene cada fichero sin tener que abrirlo.
La herramienta clave: file
file analiza el contenido de un fichero y te dice qué es. No se fía de la extensión, que en Linux no significa nada: lee los primeros bytes y los compara con firmas conocidas. Así distingue un texto plano (ASCII text), una imagen, un ejecutable o datos binarios sin formato reconocible (data).
Mi solución: find | xargs file
1
bandit4@bandit:~/inhere$ find . -type f -readable | xargs file
La salida muestra una línea por fichero con su tipo. Nueve salen como data y solo uno como ASCII text: ese es el nuestro.
Por partes:
find .busca a partir del directorio actual (.).-type fse queda solo con ficheros, no con directorios.-readablese queda con los ficheros que nuestro usuario puede leer. Es un filtro de permisos, no de contenido. Aquí no descarta nada, porque podemos leer todos; quítalo y verás el mismo resultado. Es útil en otros escenarios, cuando buscas por un sistema entero y no quieres que se te llene la pantalla de ficheros que no puedes abrir.| xargs file:findimprime una lista de rutas, una por línea.xargscoge esa lista y la convierte en argumentos parafile. Es decir, ejecutafile ./-file00 ./-file01 ...con todas las rutas a la vez.
¿Por qué hace falta xargs? Porque file no lee la lista de ficheros de la entrada estándar: espera recibirlos como argumentos. Con find ... | file a secas no funcionaría. xargs hace de puente entre “salida de un comando” y “argumentos de otro”.
Y un detalle que lo hace funcionar: find devuelve las rutas como ./-file00, con ./ delante. Es el mismo truco del nivel 1 → 2, así que file no confunde los nombres con opciones aunque empiecen por guion.
Con el fichero localizado, lo leemos. No te digo cuál es, compruébalo tú:
1
2
bandit4@bandit:~/inhere$ cat ./-file0X
[REDACTED]
Otras formas de resolverlo
1
2
3
bandit4@bandit:~/inhere$ file ./*
bandit4@bandit:~/inhere$ find . -type f -exec file {} +
bandit4@bandit:~/inhere$ find . -type f | xargs file | grep text
file ./*: la más corta. El*lo expande la shell a todos los ficheros del directorio. Fíjate en el./: confile *a secas, la shell pasaría-file00,-file01… yfilelos tomaría por opciones. Otra vez el truco del nivel 1 → 2.find . -type f -exec file {} +: hace lo mismo quexargssin salir defind.{}se sustituye por las rutas encontradas y+le dice que las pase todas juntas en una sola ejecución.... | grep text: añade un filtro final para que solo aparezca la línea que interesa. Con diez ficheros da igual, pero con mil es la diferencia entre leer una línea o mil.
xargsy los espacios.xargssepara los argumentos por espacios, así que se rompería con nombres como el--spaces in this filename--del nivel 2 → 3. La versión robusta esfind . -type f -print0 | xargs -0 file, que separa las rutas con un carácter nulo en vez de con espacios. O directamente-exec, que no tiene ese problema.
Pasar al nivel 5
1
2
bandit4@bandit:~/inhere$ exit
$ sshpass -p '[REDACTED]' ssh bandit5@bandit.labs.overthewire.org -p 2220
Resumen
| Comando / concepto | Para qué sirve |
|---|---|
| human-readable | Contenido legible por una persona (texto), no “con permisos de lectura” |
file fichero | Identificar el tipo de contenido por sus bytes, no por la extensión |
find . -type f | Listar todos los ficheros a partir de un directorio |
-readable | Filtrar por permisos de lectura del usuario actual |
xargs comando | Convertir la salida de un comando en argumentos de otro |
find ... -exec cmd {} + | Ejecutar un comando sobre lo encontrado sin usar xargs |
reset | Recuperar la terminal si se descontrola tras mostrar datos binarios |