Entrada

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.

Bandit: nivel 20 → 21

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:

  1. Se conecta a un puerto de localhost que tú le indicas por línea de comandos.
  2. Lee una línea de texto de esa conexión.
  3. La compara con la contraseña del nivel actual (bandit20).
  4. 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ónQué hace
-lModo listen: en vez de conectarse, se queda escuchando (servidor)
-nNo resolver DNS; trabaja con IPs directamente (más rápido)
-vVerbose: muestra información de la conexión cuando alguien se conecta
-p 4444El 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 root puede 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/bandit20 le da al nc la contraseña directamente por la entrada estándar, así no hay que pegarla a mano. En cuanto alguien se conecte, nc se la envía.
  • El & del final deja el nc corriendo en segundo plano, y nos devuelve el prompt para poder lanzar el suconnect a 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 / conceptoPara qué sirve
nc -lnvp 4444Poner netcat a escuchar (servidor) en el puerto 4444
-l / -pModo escucha / puerto
-n / -vSin 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 > 1024Los que puede abrir un usuario sin ser root
mkfifoCrear una tubería con nombre (comunicación bidireccional)
Esta entrada está licenciada bajo CC BY 4.0 por el autor.