RootedCon CTF writeup nivel 3

Reto 3

Como vimos en el reto anterior, tenemos corriendo un knockd que nos abre un ssh en el puerto 22.

Si no sabes lo que es el port knocking puedes ver cómo funciona aquí: http://es.wikipedia.org/wiki/Golpeo_de_puertos

Como resumen, diré que se trata de un mecanismo de seguridad que oculta ciertos servicios y los abre recibiendo una secuencia mágica de números.

En este caso, todos los puertos que espera knockd son TCP, por lo que para que nos de acceso, le mandaremos la secuencia mágica, para posteriormente conectarnos por ssh:

Accedemos con nuestro usuario y contraseña:

Y analizamos un poco el entorno.

En nuestro directorio no vemos nada de utilidad pero si retrocedemos un directorio, en /home/ hay un segundo usuario cuyo nombre nos incita a entrar 🙂 … su nombre es: pownme

Así que accedemos a su carpeta personal y hacemos un ls -la para ver lo que hay dentro:

Aquí vemos varias cosas interesantes:

  • Un binario que podemos ejecutar con suid de pownme.
  • Un fichero de configuración al que no tenemos acceso.
  • Otro fichero comprimido al que tampoco tenemos acceso.

Todo apunta a que hay que hacer una escalada de privilegios para llegar a ver el contenido de ese fichero comprimido, así que vamos a ver qué hace el binario:

Bueno, pues está claro que se trata de un overflow. Llegados a este punto necesitamos obtener algo de información para ver con qué nos enfrentamos, si tenemos que crear un exploit o simplemente hay que machacar algún dato.

Sacamos algo de información del sistema:

A primera vista ya nos encontramos con varios problemas:

  • Por un lado se trata de una arquitectura de 64 bits.
  • Por otro lado, tenemos activado el randomize_va_space.
  • El binario no tiene permisos de lectura, por lo que no podemos descargarlo a nuestra máquina y usar luego el EDB, IDA Pro o nuestro debugger favorito.
  • No hay ningún depurador instalado en la máquina, por lo que tampoco podemos depurar ahí.

Llegados a este punto sólo nos queda probar a mano:

Tras realizar varias pruebas al final vemos algo interesante introduciendo el usuario seguido de diferentes \x01:

Vemos que ya no da error de permisos pero tampoco saca los datos completos. Así que vamos a probar con \x02:

Y ya, por curiosidad, si ponemos un \x03:

Pues parece hemos sobrescrito en número de líneas a imprimir, a parte de otra cosa, que nos permite ver los datos de otro usuario.

Introducimos el usuario y la contraseña obtenida para pasar el reto: pownme:c@r@m3l0_0.o

———————————————————————————-

Nota: La verdad es que no comprendí muy bien cómo pasé el reto ya que fui probando bytes hasta que ‘de casualidad’ me apareció la contraseña por pantalla.

Ya, por mera curiosidad y, en casita, me descargué el binario (ahora que ya tenemos la contraseña de pownme, es fácil 🙂 y lo abrí con IDA Pro para analizarlo un poco).

Abrimos el binario con el IDA Pro para 64 bits y echamos un ojo al contenido.

>>>> Antes de nada, si meto la pata no me fustiguéis, que los binarios de 64 bits en Linux no son precisamente mi fuerte 😛 <<<<

Bien, pues de momento nos encontramos una función llamada get_value(), que tras entrar en ella podemos ver:

En la cabecera de la función vemos la inicialización de los parámetros usados, que por comodidad he renombrado:

  • nombreDeUsuario es el parámetro de entrada, donde escribimos el nombre de usuario.
  • bufferValidacion (igual el nombre que le he puesto resulta lioso) es, digamos, el umbral a partir del cual te dice si eres un Bad Boy.
  • UIDUsuario es donde se guarda el resultado de la llamada a _getuid.

Un poco más abajo vemos cómo, tras el _getuid, guarda un 0 si no tenemos permisos o un 1 si los tenemos, es decir, por defecto, con el usuario lamde, nos dejaría un 0 y no podríamos ver los datos de pownme:

Y más abajo aún tenemos la verificación de lo que he llamado bufferValidacion, que tendría el valor con el que sobrescribimos pasados los 12 bytes primeros. Y en caso de ser menor de 3, nos aparece el mensaje de ‘Bad Kid’:

Por último, tenemos la verificación de lo que almacenamos anteriormente en UIDUsuario, que como vimos, era un 0 si no tenemos acceso, y un 1 si lo tenemos:

Como podemos apreciar, si vale 0 nos manda al mensaje de ‘You can’t touch this!’ y, en caso contrario, nos mostrará los datos del usuario.

En resumen, nuestra finalidad es cambiar el valor de UIDUsuario para que nos deje mostrar los datos de pownme, pero saltándonos el filtro de bufferValidacion que nos lleva por otro camino para mostrarnos la frase Bad Kid.

Por tanto, una forma de pasarlo directamente sería introduciendo (clickea en la imagen para ampliar):

donde \x70\x6f\x77\x6e\x6d\x65 es pownme.

———————————————————————————-

Un comentario

Deja un comentario