El otro día estuve buscando un exploit en exploit-db (https://www.exploit-db.com/exploits/47334) para contar cómo se puede explotar un SBO utilizando SEH, y he pensado en compartir mi experiencia para que aquellos que estéis pensando en apuntaros al Bootcamp Exploit Development for Pentesters de RootedCON podáis ver con que tipo de ejercicios nos vamos a divertir durante los 3 días que dura el Bootcamp.
Este exploit utiliza una tecnica que permite sacar partido de los SEH de Windows en lugar de sobre escribir la dirección de retorno como se hace en los exploits con los que comenzaremos a trabajar en el Bootcamp. Ese tipo de exploit es con los que se suelen iniciar las personas que se acercan a la explotación de binarios.
Para aquellos que os estéis acercando a este POST sin haber practicado mucho estas técnicas, os haré una breve introducción para tratar de situaros.
Los programas con los que interactuamos normalmente son procesos que se componen del código que un programador ha desarrollado y su estado en memoria. Por ejemplo cuando dos usuarios empiezan a escribir un documento de Word, los dos estan utilizando el mismo código, pero a medida que van escribiendo, añadiendo figuras o índices la memoria de esos procesos el estado de los procesos (su memoria) va difiriendo.
El mapa de memoria de un proceso es donde se van almacenando el resultado de las operaciones que un usuario va realizando. Este mapa de memoria se divide en varias zonas o áreas, entre las que destacan:
- La zona de .text o código donde se alojan las instrucciones que un programa va ejecutando.
- La zona de Heap o de reserva de memoria dinámica. Este área la suelen utilizar los programas para poder alojar objetos de los que desconocen su tamaño. Un navegador por ejemplo no conoce a priori cuanto va a ocupar la página o las fotos que un usuario va a visitar. Este tipo de datos se suelen guardar en esta zona.
- La zona de Pila o Stack, donde se suelen guardar las variables locales de las funciones o para guardar valores de forma temporal mientras el código se ejecuta. También se utiliza para pasar los argumentos que debe utilizar la función. La pila también se utiliza cuando se realizan una llamada a una función. En este caso se genera un marco de pila y entre los valores que se almacenan en la pila, se guarda la dirección de retorno. Dirección por la que el programa debe continuar una vez haya terminado la ejecución de la función.
Os recomiendo que leais los tutoriales que Corelan tiene al respecto de explotación de Stack Buffer Overflows y SEH.
Vamos a remangarnos
Me llamó la atención es que el exploit me parecía un poco complejo para los que se suelen ver en exploit-db, así que decidí consultar el post en el que el autor explicaba como había realizado el mismo. Una vez leido tengo claro que en el fichero de configuración del programa vulnerable hay determinados campos que son vulnerables a un ataque de Stack Buffer Overflow. Un buffer es una region de memoria contigua. Un buffer Overflow se produce cuando un programa escribe fuera de los límites del buffer. Un Stack Buffer Overflow se produce cuando un programa escribe fuera de los límites de un Buffer que se encuentra en la Pila o Stack.
Lo primero que hice fue generar un fichero python que reprodujera las condiciones de fallo. En este caso el parámetro ProjectPath del fichero de configuración le puse como valor 5000 As. Al ejecutar el programa en el depurador vemos que se produce una excepción que no me permite controlar el EIP de directa. Pero podemos ver que hemos afectado al SEH, esto me hace iniciar el exploit pensando en esa tecnica de explotación.
En el momento que estuve haciendo este ejercicio no me di cuenta de que este excepción se produce por escribir fuera de los límites de la pila y que se podría explotar modificando la dirección de retorno. Para ello utilizamos mona y le pedimos que nos calcule un patron de longitud 5000 y lo añadimos a nuestro exploit. Al volver a ejecutar el programa con este cambio se vuelve a producir la excepción de escritura fuera de los limites de la pila y es el momento de utilizar mona con el comando findmsp. Este comando nos permite conocer algunos valores muy utiles a la hora de explotar el programa vulnerable.
El siguiente paso consite en crear un patron que nos ayude a detectar la distancia hasta las zonas que nos interesa afectar para lograr la ejecución de código. Para ello usamos mona pc y mona findmsp
A continuación ejecutamos mona seh para que nos indique direcciones con una secuencia de instrucciones pop, pop, ret que nos permitirán redirigir la ejecución del programa hacia la pila, zona sobre la que podemos influir.
Al ver el resultado podemos observar que el único modulo que no esta protegido por SafeSEH es el propio ejecutable, esto proboca que sólo podamos utilizar la parte inicial del buffer y que tengamos que poner un salto hacia atrás en lugar de hacia delante como se suele hacer en la explotación de SEH. Cuando pongamos todo esto en el exploit es donde nos damos cuenta que ya no se produce la escritura fuera de la pila ya que al poner un \x00 no se continúa con la escritura en el buffer.
En el POST del autor del exploit parece existir algún módulo sin SafeSEH lo cual le permitiría utilizar otros gadgets que no terminen en \x00. En nuestro caso no queda mas remedio que utilizar partes del .exe
Con la direccion que contiene pop, pop, ret, un salto corto hacia atrás y una shellcode “pequeña” que hace que se invoque a la calculadora, podemos validar la ejecución de código.
Una vez hemos validado la ejecución de código ya “sólo” nos falta sustituir el payload de la calculadora por un payload un poco más “util” como puede ser una conexión inversa hacia un servidor que controle el atacante. Para ello utilizamos msfvenom.
El siguiente reto a superar son los “bad characters” o caracteres que hacen que el exploit no funcionen. En este caso tenemos unos cuantos, pero que gracias a mona y la función bytearray podemos detectar cuales son. Al final descartamos los caracteres 00 0a 0d 1a 20 3d y 3f y así se lo indicamos a msfvenom. También le indicamos que queremos el payload en formato python ya que el exploit lo estamos desarrollando en ese lenguaje.
Ya que el payload es más largo que el anterior tenemos que establecer un segundo salto hacia atrás (un salto largo que ocupa 5 bytes) después de un salto corto que ocupa 2. Gracias a la herramienta metasm de metasploit podemos obtener el código binario de esas instrucciones.
Una vez completado el exploit verificamos que funciona desde el depurador y una vez logrado sólo nos queda probarlo desde fuera del mismo. Si conseguimos que funcione directamente ya podemos enviarle el fichero de configuración a nuestra víctima para tomar el control de su máquina
Este es un ejemplo de los ejercicios que estaremos haciendo a lo largo del Bootcamp Exploit Development for Pentesters de RootedCON. Este ejemplo lo hemos realizado sin protección DEP ni ASLR, protecciones que vermos como podemos sobrepasar para poder seguir teniendo ejecución de código en estas circustancias.
Gracias por leer esta entrada y nos vemos en la red.