CTF Brainpan

Post on 15-Apr-2017

61 views 2 download

Transcript of CTF Brainpan

Solución al CTF Brainpan

Objetivo: comprometer el sistema consiguiendo acceso root.

@diegorg

Nada más iniciar la máquina virtual (BRAINPAN) presenta un login.

no iba a ser tan fácil ;-)

Pruebo con varios passwords sin éxito.

Busco la IP de la máquina objetivo (BRAINPAN).

Empiezo por comprobar qué puertos y servicios tiene a la escucha

Tenemos abiertos los puertos 9999 y el 10000, además también veo que se trata de un máquina Linux.

En el puerto 9999 está a la escucha probablemente el servicio Abyss Web Server.

Realizo un escaneo de directorios

La respuesta es que no es un servicio web lo que está escuchando en ese puerto.

Si accedo a ese directorio en el navegador obtengo esto

Es la misma pantalla que cuando se inicia BRAINPAN, pero devuelve texto, no se pueden introducir credenciales.

En el puerto 10000 está a la escucha el servicio SimpleHTTPServer 0.6.

Realizo un escaneo de directorios sobre ese puerto.

Se ha encontrado el directorio /bin

Accedo a través del navegador, primero lo haré sin incluir en la url el directorio encontrado previamente.

La página que se muestra no es más que una imagen, aunque es de obligada lectura para desarrolladores web ;-)

Ahora lo hago incluyendo en la url el directorio /bin.

Me devuelve el contenido del directorio con un único fichero.

Lo descargo.

Determino qué tipo de fichero es.

Se trata de un ejecutable de Windows.

Lo ejecuto con wine en mi equipo.

Indica que está a la escucha en el puerto 9999.

Y así es.

Hago una conexión al puerto 9999 de mi equipo para ver qué hace brainpan.exe.

Me solicita un password.

Vuelvo a ejecutar brainpan.exe pero ahora desde el debugger para Windows.

Realizo de nuevo una conexión.

Analizo el funcionamiento de brainpan.exe a través del debugger.

Si introduzco un password, la respuesta es ACCESS DENIED y finaliza la conexión.

Descubro con el debugger que el password válido es shitstorm.

Aunque ese password para lo único que sirve es para despistar :-)

Al analizar el código no he visto que se filtre la entrada del password, por lo que es posible que sea vulnerable a un buffer overflow.

Utilizo la herramienta para fuzzear sfuzz. Preparo primero el fichero fuzz.cfg para una entrada de por ejemplo, 3000 caracteres A.

Ejecuto de nuevo brainpan.exe pero ahora fuera del debugger.

Y lanzo el fuzzer contra mi equipo en el puerto 9999.

Efectivamente, no está controlada la entrada del password y se produce un buffer overflow.

Voy a preparar un exploit y sacarle partido al desbordamiento de buffer.

Lo primero que necesito es averiguar en dónde exactamente se produce el desbordamiento.

Genero un patrón de 3000 caracteres. La misma cantidad usada en el fuzzer.

Ejecuto de nuevo brainpan.exe en mi equipo y me conecto introduciendo como password el patrón de caracteres anterior.

Cuando se produce el desbordamiento, la dirección a la que intenta acceder es la 0x35724134.Esa dirección corresponde a la parte del patrón de caracteres que he introducido, justo a partir de donde se desborda.

Hago una búsqueda de ese patrón para averiguar a partir de qué posición se produce el buffer overflow.

Necesito encontrar un JMP ESP en alguna parte del ejecutable.

Abro brainpan.exe en el debugger y busco la instrucción.

La encuentro en la dirección 0x311712F3

Esa dirección es la que debe estar a partir de la posición 525 para que salte al ESP y ejecute mi shellcode.

Genero el shellcode que incluiré como payload de mi exploit.

El shellcode que he escogido es para Linux.

Pone a la escucha el puerto 4444 en la máquina BRAINPAN.

Y proporcionará una shell al conectar en ese puerto.

Creo el script exploit.pl que conectará con la máquina BRAINPAN, provocará el buffer overflow y se ejecutará el payload, quedando a la escucha en el puerto 4444 y proporcionándome una shell cuando me conecte.

Ejecuto el exploit.pl

Si el exploit tuvo éxito, lo primero que tendré será el puerto 4444 abierto. Lo compruebo y así es.

Establezco los parámetros del multi/handler de metasploit para conectar al puerto 4444 y lo ejecuto.

La conexión se efectuó y ya dispongo de una shell en la máquina BRAINPAN como usuario puck. Este es el usuario que está ejecutando brainpan.exe

Recopilo información del sistema.

Me encuentro con que puck es un usuario incluido en sudoers, que tiene privilegios para ejecutar el binario anansi_util con privilegios de root

Ya tengo acceso a BRAINPAN, ahora tengo que buscar la forma de conseguir root y resolver el reto comprometiendo completamente el sistema.

Solo puedo ejecutar el binario porque pertenece seguramente al usuario anansi.

Al ejecutar el binario, este indica que hay que introducir uno de los tres posibles parámetros (network, proclist, manual)

Pasando el parámetro network, muestra la configuración de la red. Es el comando ip address el que se ejecuta.

Pasando el parámetro proclist, obtengo un error como respuesta

Para evitar el error creo la variable de entorno TERM con el valor xterm

Pruebo de nuevo y aparece otro error. Por lo que se ve, intenta ejecutar el comando top

Con dispongo de python, con esta sencilla línea creo una shell con tty y evito el error.

Ejecuto de nuevo sudo /home/anansi/bin/anansi_util proclist

Como se esperaba, es el comando top el que se ejecuta.

Por último, queda probar con el parámetro manual al que hay que añadir un comando.

Lo ejecuto pasándole el comando id.

Y me aparece la ayuda de ese comando, por lo que se entiende que está utilizando el comando man.

Por tanto, lo que hace el binario anansi_util es ejecutar los comandos top, ip y man con privilegios root.

El comando man tiene la peculiaridad de que si le pasas como parámetro un fichero de texto, lo abre.

Si a través de sudo, anansi_util ejecuta man como root, entonces pruebo a pasarle /etc/shadow a ver qué pasa.

Y lo que pasa es lo que esperaba, se muestra el contenido de shadow.

La idea ahora es crackear el fichero shadow para obtener el password de los usuarios que pueda. Lo ideal sería obtener el de root, pero si no es posible, el de anansi sería el más interesante porque podría intentar modificar el binario anansi_util para que ejecute el comando que yo le indique. Al ejecutarse este con privilegios root, podría comprometer el sistema.

Creo en mi sistema fichero_shadows.txt con solo los usuarios que quiero crackear.

Lanzo la herramienta para crackear los passwords.

Y… No consigo crackear ninguno :-(

Cuando comencé a recopilar información, busqué todos los suids binarios

De todos los resultados, me llamó la atención el binario validate que pertenece al usuario anansi

Cuando lo ejecuto indica que debo entrar un parámetro

Pruebo con varios y el resultado siempre es el mismo, validating input...passed y en alguna ocasión un error de validación. Nada más.

Si la entrada del dato que se le pasa como argumento no está filtrada, posiblemente se produzca un buffer overflow.

Pruebo con un parámetro largo, por ejemplo pasando 450 caracteres.

Muestra un Segmentation fault porque efectivamente se ha producido un buffer overflow.

Voy a descargar en mi sistema el binario validate para analizarlo y crear el exploit.

Para ello, primero copio el fichero en el directorio desde el que podré descargarlo vía servicio web.

Genero un patrón de 450 caracteres que introduciré como valor de entrada en el binario para provocar el exploit y averiguar a partir de qué dirección de memoria se produce el desbordamiento.

Como se trata de un suid binario perteneciente al usuario anansi, si aprovecho el buffer overflow para introducir un shellcode conseguiré que este se ejecute con los privilegios del propietario.

Y desde mi sistema lo descargo.

Con gdb cargo el binario y paso como parámetro el patrón generado anteriormente.

Al ejecutarlo se produce el buffer overflow y muestra la dirección incorrecta 0x39644138.

Esa dirección corresponde a una parte del patrón que le he pasado.

Partiendo de esa dirección, averiguo el offset a partir de donde se produce el desbordamiento.

Necesito saber si en la máquina BRAINPAN está habilitado ASLR. Dependiendo de si está activo o no, la creación del exploit cambia.

Y así es, randomize_va_space tiene valor 2.

Con ldd se puede ver que en cada ejecución las librerías se cargan en direcciones distintas.

Como ASLR está habilitado, usaré la técnica RET2EAX.

Para realizar esta técnica necesito saber en qué dirección se encuentra la llamada call *%eax dentro de la función __do_global_ctors_aux que se crea al compilar el binario.

Abro con el gdb el binario y desensamblo la función. El call *%eax se encuentra en 0x0804862b <+27>

En el exploit exp.c que he creado he introducido un payload que se le pasará a validate formado por: - Un shellcode de 28 bytes.- Más 88 bytes de relleno para que sumen 116 bytes.- Más 4 bytes que sobrescriben la dirección de retorno y que corresponden a la dirección 0x0804862b del

call *%eax que localicé anteriormente y que redireccionará y ejecutará mi shellcode execve(“/bin/sh”)

Compilo y subo el exploit exp a la máquina BRAINPAN.

El binario exp no tiene el bit de ejecución activo.

Lo activo.

Ahora sí.

Cambio al directorio donde se encuentra validate y ejecuto el exploit exp.

El exploit ha funcionado con éxito, se ha abierto una nueva shell con el uid efectivo correspondiente al usuario anansi, con lo que ya tengo privilegios de este usuario también.

Ahora sí puedo cambiar al directorio (propietario anansi) en donde se encuentra el binario anansi_util.

Ya tengo acceso a anansi_util. Como indiqué anteriormente, el usuario puck está como sudoer y puede ejecutar este binario con privilegios root, así que la idea es modificarlo y sustituir uno de los comandos que ejecuta por otro de mi elección.

No puedo copiarlo directamente a /home/puck/web porque estoy como usuario anansi, así que, primero lo copio al directorio /tmp que tiene permisos de escritura, después abandono la shell para volver a ser el usuario puck y a continuación lo copio al directorio desde donde podré descargarlo.

Ahora ya lo puedo descargar en mi sistema.

Edito el binario para localizar los comandos que permite ejecutar (top, ip y man)

Se pueden ver los comandos que ejecuta y los parámetros pasados, por ejemplo /usr/bin/top -n1

Ese es el comando que voy a sustituir por el que yo quiera. El comando que introduzca tiene que ocupar el espacio que ahora ocupa /usr/bin/top -n1. Para evitar ese problema de espacio, lo que voy a hacer es introducir la llamada al bash ./cmd.sh. En este incluiré todos los comandos que necesite.

Y lo que quiero que haga cmd.sh cuando se ejecute es añadir el usuario glider con privilegios root y que me solicite el password que le quiero asignar.

A continuación sustituyo -n1 /usr/bin/top por ./cmd.sh

Subo al sistema BRAINPAN cmd.sh y anansi_util modificado.

Me encuentro como usuario puck y hay que dejar anansi_util en /home/anansi/bin.

Lo primero será copiarlo al directorio /tmp para después, estando como anansi, copiarlo al directorio destino.

La copia de anansi_util la haré con otro nombre porque en /tmp ya existe y el propietario es anansi con lo que no podré sobrescribirlo.

cmd.sh lo dejo donde lo he descargado /home/puck/web porque en anansi_util introduje ./cmd.sh por lo que cuando ejecute el binario, buscará el bash en el directorio en el que me encuentre.

Copio anansi_util_modificado al directorio de bin de anansi, la copia la hago con el nombre original para sobrescribir el que hay.

Habilito la ejecución de cmd.sh.

Necesito ejecutar de nuevo el exploit de validate para conseguir una shell del usuario anansi.

Ya solo queda abandonar la shell para volver a ser el usuario puck.

Ejecuto como sudoer anansi_util y de argumento le paso proclist que es el que ejecutaría el comando top y que he sustituido por cmd.sh.

Cambio al directorio en donde tengo cmd.sh.

Como tenía previsto, me pide que asigne un password para el usuario glider que ya habrá sido incluido como root.

Ya solo queda cambiar al usuario glider.

Para evitar el error al hacer su, ejecuto de nuevo la línea de python para crear una shell con tty.

¡¡Conseguido!! el sistema ha sido comprometido

Solo me queda ver si hay algo escondido en el directorio del usuario root.

Encuentro el fichero b.txt cuyo contenido es el nombre del CTF.

@diegorg