Bandit: nivel 20 → 21
Cómo resolver el nivel 20 → 21 de OverTheWire Bandit montando un servidor con netcat para alimentar a un binario SUID, con dos terminales o con un solo comando en segundo plano.
Hasta ahora hemos usado nc como cliente: nos conectábamos a un servicio que ya estaba escuchando. En este nivel le damos la vuelta: vamos a montar nuestro propio servidor con nc, y un binario del sistema se conectará a nosotros. Es la primera vez que usamos netcat en modo escucha, algo que harás constantemente al recibir shells inversas en un pentest.
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
$ sshpass -p '[REDACTED]' ssh bandit20@bandit.labs.overthewire.org -p 2220
bandit20@bandit:~$ export TERM=xterm
El enunciado
El enunciado del nivel dice que hay un binario SUID, suconnect, que:
- Se conecta a un puerto de
localhostque tú le indicas por línea de comandos. - Lee una línea de texto de esa conexión.
- La compara con la contraseña del nivel actual (bandit20).
- Si es correcta, devuelve la contraseña del siguiente nivel (bandit21).
1
2
3
4
5
bandit20@bandit:~$ ls
suconnect
bandit20@bandit:~$ ./suconnect
Usage: ./suconnect <portnumber>
This program will connect to the given port on localhost using TCP. If it receives the correct password from the other side, the next password is transmitted back.
El detalle importante: suconnect se conecta a un puerto, no escucha. Es un cliente. Así que alguien tiene que estar escuchando en ese puerto y, cuando suconnect se conecte, mandarle la contraseña de bandit20. Ese “alguien” lo montamos nosotros con nc.
La solución: dos terminales
Terminal 1: montar el servidor con netcat
Abro una segunda sesión SSH como bandit20 (otra terminal) y pongo a nc a escuchar en un puerto cualquiera por encima del 1024, por ejemplo el 4444:
1
2
bandit20@bandit:~$ nc -lnvp 4444
listening on [any] 4444 ...
Desglose de las opciones:
| Opción | Qué hace |
|---|---|
-l | Modo listen: en vez de conectarse, se queda escuchando (servidor) |
-n | No resolver DNS; trabaja con IPs directamente (más rápido) |
-v | Verbose: muestra información de la conexión cuando alguien se conecta |
-p 4444 | El puerto en el que escuchar |
¿Por qué el 4444 y no uno más bajo? Los puertos por debajo del 1024 están reservados y solo
rootpuede abrirlos. Como usuario normal tienes que elegir uno alto. El 4444 es una convención muy habitual, pero vale cualquiera libre entre 1025 y 65535.
nc se queda ahí “colgado”, esperando. Es lo normal: está escuchando.
Terminal 2: lanzar suconnect contra ese puerto
En la primera terminal ejecuto el binario diciéndole que se conecte al puerto donde está escuchando el nc:
1
bandit20@bandit:~$ ./suconnect 4444
En ese momento, en la terminal del nc verás que entra una conexión (gracias al -v). Ahora suconnect está esperando recibir una línea de texto.
De vuelta en la Terminal 1: mandar la contraseña
En la terminal del nc, escribo (o pego) la contraseña de bandit20 y pulso Enter. nc se la envía a suconnect por la conexión, este la compara, y como es correcta responde con la contraseña de bandit21, que aparece en la misma terminal del nc:
1
2
3
4
5
bandit20@bandit:~$ nc -lnvp 4444
listening on [any] 4444 ...
connect to [127.0.0.1] from [127.0.0.1] ...
[REDACTED] <- aquí pego la contraseña de bandit20 y pulso Enter
[REDACTED] <- suconnect responde con la de bandit21
Y en la terminal de suconnect verás un Read: ... y Password matches, sending next password.
Otras formas de hacerlo
1. Sin dos terminales: todo en un comando
Montar dos sesiones SSH es un poco engorroso. Podemos hacerlo todo en una sola terminal dejando el nc en segundo plano:
1
2
bandit20@bandit:~$ nc -lnvp 4444 < /etc/bandit_pass/bandit20 &
bandit20@bandit:~$ ./suconnect 4444
Lo que pasa aquí:
< /etc/bandit_pass/bandit20le da alncla contraseña directamente por la entrada estándar, así no hay que pegarla a mano. En cuanto alguien se conecte,ncse la envía.- El
&del final deja elnccorriendo en segundo plano, y nos devuelve el prompt para poder lanzar elsuconnecta continuación.
Cuando ejecutas suconnect 4444, se conecta al nc que está de fondo, este le manda la contraseña, y la respuesta (la de bandit21) aparece por pantalla.
2. Una tubería con nombre (FIFO)
Una variante más “elegante” usando una named pipe, por si el servidor necesitara una conversación de ida y vuelta:
1
2
3
bandit20@bandit:~$ mkfifo /tmp/f
bandit20@bandit:~$ nc -lp 4444 < /etc/bandit_pass/bandit20 &
bandit20@bandit:~$ ./suconnect 4444
Para este nivel no hace falta (la comunicación es de una sola dirección), pero mkfifo es un patrón que reaparece mucho cuando montas shells inversas interactivas, así que conviene conocerlo.
Pasar al nivel siguiente
1
2
bandit20@bandit:~$ exit
$ sshpass -p '[REDACTED]' ssh bandit21@bandit.labs.overthewire.org -p 2220
El siguiente nivel cambia de tema: entran en juego los cron jobs, tareas programadas que el sistema ejecuta automáticamente cada cierto tiempo.
Resumen
| Comando / concepto | Para qué sirve |
|---|---|
nc -lnvp 4444 | Poner netcat a escuchar (servidor) en el puerto 4444 |
-l / -p | Modo escucha / puerto |
-n / -v | Sin resolución DNS / modo verboso |
./suconnect <puerto> | Cliente SUID que se conecta y espera la contraseña |
nc ... < fichero & | Enviar un fichero por la conexión y dejar el proceso en segundo plano |
& | Ejecutar un comando en segundo plano |
| Puertos > 1024 | Los que puede abrir un usuario sin ser root |
mkfifo | Crear una tubería con nombre (comunicación bidireccional) |