Bandit: nivel 21 → 22
Cómo resolver el nivel 21 → 22 de OverTheWire Bandit leyendo un cron job que vuelca la contraseña en /tmp, con una introducción a la sintaxis de crontab.
Cambiamos de tema: entran los cron jobs, el planificador de tareas de Linux que ejecuta programas automáticamente cada cierto tiempo. En este nivel no tenemos que explotar nada; basta con leer qué hace una tarea programada y recoger lo que deja por el camino. Pero entender cron es importante: muchas escaladas de privilegios reales se basan en tareas programadas mal configuradas.
Las contraseñas de los niveles aparecen como [REDACTED]. Siguiendo las normas de OverTheWire, no publico credenciales: la gracia es que llegues a ellas tú.
Conexión
1
2
3
4
$ sshpass -p '[REDACTED]' ssh bandit21@bandit.labs.overthewire.org -p 2220
bandit21@bandit:~$ export TERM=xterm
bandit21@bandit:~$ ls
bandit21@bandit:~$
Home vacío. La pista no está aquí, sino en la configuración del sistema.
El enunciado
El enunciado del nivel dice que hay un programa ejecutándose automáticamente a intervalos regulares desde cron, el planificador de tareas basado en tiempo. Nos dice que miremos en /etc/cron.d/ para ver la configuración y averiguar qué comando se ejecuta.
Paso 1: leer la configuración del cron
1
2
3
4
5
bandit21@bandit:~$ ls /etc/cron.d/
... cronjob_bandit22 ...
bandit21@bandit:~$ cat /etc/cron.d/cronjob_bandit22
@reboot bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
Hay que saber leer estas dos líneas:
@reboot: ejecuta el comando una vez, cada vez que la máquina arranca.* * * * *: son los cinco campos de tiempo de cron. Cinco asteriscos significan “cada minuto, de cada hora, de cada día…”. O sea, la tarea se ejecuta una vez por minuto.bandit22: el usuario con cuyos permisos se ejecuta la tarea. Esto es clave: el script corre como bandit22, no como nosotros./usr/bin/cronjob_bandit22.sh: el script que se ejecuta.&> /dev/null: redirige tanto la salida estándar (stdout) como los errores (stderr) a/dev/null, es decir, tira toda la salida a la basura. Por eso no vemos nada por pantalla aunque se esté ejecutando cada minuto.
Los cinco campos de cron, de izquierda a derecha, son:
| Campo | Significado | Rango |
|---|---|---|
| 1 | Minuto | 0-59 |
| 2 | Hora | 0-23 |
| 3 | Día del mes | 1-31 |
| 4 | Mes | 1-12 |
| 5 | Día de la semana | 0-7 (0 y 7 = domingo) |
Un * en un campo significa “todos los valores”. Así que * * * * * = cada minuto.
Paso 2: leer el script
1
2
3
4
bandit21@bandit:~$ cat /usr/bin/cronjob_bandit22.sh
#!/bin/bash
chmod 644 /tmp/<fichero>
cat /etc/bandit_pass/bandit22 > /tmp/<fichero>
Lo que hace el script, ejecutándose como bandit22:
chmod 644 /tmp/<fichero>: pone permisos de lectura para todo el mundo (rw-r--r--) sobre un fichero en/tmp.cat /etc/bandit_pass/bandit22 > /tmp/<fichero>: vuelca la contraseña de bandit22 en ese fichero.
Es decir, cada minuto bandit22 escribe su propia contraseña en un fichero de /tmp que cualquiera puede leer. No necesitamos ejecutar nada ni esperar: el fichero ya está ahí (la tarea lleva corriendo desde hace rato).
La solución
Solo hay que leer ese fichero:
1
2
bandit21@bandit:~$ cat /tmp/<fichero>
[REDACTED]
Y ya tenemos la contraseña de bandit22.
El nombre del fichero en
/tmpes una cadena larga y aleatoria. Lo dejo como<fichero>a propósito: cópialo tal cual lo veas en tu salida delcatdel script, porque cambia con cada reinicio del juego.
Por qué esto importa en seguridad
Aquí el cron solo filtra una contraseña, pero el patrón “una tarea privilegiada toca ficheros en una ruta a la que yo tengo acceso” es una de las vías de escalada de privilegios más explotadas del mundo real. Si en lugar de leer un fichero de /tmp, el cron ejecutara un script sobre el que tú tienes permiso de escritura, podrías meter tus propios comandos y hacer que se ejecutaran con los privilegios de ese usuario (justo lo que pasa en el siguiente nivel).
Por eso, al auditar una máquina, revisar los crons es casi obligatorio:
1
2
bandit21@bandit:~$ ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/
bandit21@bandit:~$ cat /etc/crontab
Herramientas de enumeración como
linpeasrevisan todo esto automáticamente, pero conviene saber hacerlo a mano para entender qué está mirando la herramienta.
Pasar al nivel siguiente
1
2
bandit21@bandit:~$ exit
$ sshpass -p '[REDACTED]' ssh bandit22@bandit.labs.overthewire.org -p 2220
El siguiente nivel sigue con cron, pero sube el listón: tendrás que leer un script y razonar qué nombre de fichero genera antes de poder recoger la contraseña.
Resumen
| Comando / concepto | Para qué sirve |
|---|---|
cron | Planificador de tareas por tiempo |
/etc/cron.d/ | Directorio con configuraciones de cron del sistema |
* * * * * | Los 5 campos de tiempo: aquí, “cada minuto” |
@reboot | Ejecutar al arrancar la máquina |
&> /dev/null | Descartar stdout y stderr |
chmod 644 | Permisos rw-r--r-- (lectura para todos) |
cat fichero > destino | Volcar el contenido de un fichero en otro |