INTRODUCCIÓN
Hola a todos, en este artículo vamos a resolver la explotación del binario VULNSERVER, Específicamente la función LTER para aquellos que estén animados a presentar su examen de OSCE de offensive Security, creo que le puede servir este artículo, quien no, pues aprende acá y ahora conmigo, la idea primordial es explicar los pasos fundamentales de explotación y como descubrir dicha vulnerabilidad desde cero, adicional, superar la cantidad de obstáculos que se nos presentarán. Pueden encontrar el material usado para este artículo en el siguiente link.
¿A QUÉ NOS ENFRENTAMOS?
En esta publicación en particular vamos a tratar el tema de recreación de la sobre escritura de SEH (Structure Exception Handler), usaremos saltos negativos, stack pivot y encodearemos a mano nuestras cargas útiles o payloads luchando con los badchars, para poder ejecutar código remoto.
LO QUE NECESITAMOS
Para resolver este software necesitamos de las siguientes herramientas:
- Immunity Debugger y/o Ida Free
- Un editor de código (SublimeText/PycharmCommunity/VisualStudioCode)
- El binario VULNSERVER
- boofuzz
- Burpsuite Community
- Windows 10 PRO N o XP SP3
Vamos a dividir esta explotación en dos fases:
FASE REVERSING: En esta fase haremos un análisis estático al binario donde reversaremos la función LTER y encontraremos el fallo solo reversando.
FASE DINAMICA: En esta fase haremos uso de software como boofuzz para realizar fuzzing sobre el binario y descubrir el fallo de forma dinámica.
ANÁLISIS ESTÁTICO
Para esta fase voy hacer uso de la herramienta IDA, puede ser la versión Free o PRO, igual el análisis estático funciona igual en cualquier versión, lo hago con esta herramienta por que es más comoda para mi gusto, ustedes pueden usar la que mejor se ajuste a su necesidad.
REVERSANDO Y ENCONTRANDO EL FALLO
Lo primero será abrir nuestro binario VULNSERVER desde IDA.

Apertura de VULNSERVER en IDA PRO
Lo primero que haremos será buscar las strings del binario y ver si encontramos palabras relacionadas a LTER.

Busqueda de String’s LTER en VULNSERVER
Damos doble click sobre la primera string LTER en .rdata:00404477, buscamos sus referencias presionando X sobre la palabra LTER luego de haber presionado doble click, de la siguiente forma.

Busqueda de referencias a LTER
Vamos a la referencia que nos muestra el ida y llegamos a la siguiente zona.

Inicio Funcion LTER en VULNSERVER
int strncmp ( const char * str1, const char * str2, size_t num );
_str1: Cadena C para comprar
Parametros funcion _strncmp
_str2: Cadena C para comparar
_num: Número máximo de caracteres para comparar ( size_t es un tipo integral sin signo.)
Lo primero que logramos observar es el uso de la función _strncmp la cual
compara caracteres de dos cadenas, compara hasta _num caracteres de la cadena C _str1 con los de la cadena C _str2. Esta función comienza a comparar el primer carácter de cada cadena. Si son iguales entre sí, continúa con los siguientes pares hasta que los caracteres difieran, hasta que se llegue a un carácter nulo de terminación o hasta que los caracteres numéricos coincidan en ambas cadenas, lo que ocurra primero.
Luego de pasar estas comparaciones vienen unas inicializaciones de buffer dinámicas en memoria con malloc, de 0x1000 y luego llena los bloques de reservados con memset.
Si seguimos traceando vemos algo interesante y es que va a leer nuestro buffer posición por posición y lo va comparando nuestros datos con 0.

Comparacion de bytes de nuestro buffer con cero
Esta comparación tiene algo importante y es que si no es mayor o igual a 0, se va activar la bandera SF la cual será usada por el siguiente código, tomando el valor que contiene la posición del buffer en ese momento y lo resta con 0x7f.

Modificacion de bytes mayores a 0x7f de nuestra payload
Una vez terminada de hacer todas esas jugadas, encontramos una última comparación donde en la posición de nuestro buffer compara con 0x2e o «.».

Comparacion para entrar a funcion vulnerable
Ojo que si no tenemos el 0x2e para comparar no podremos entrar a la función _Function3, que por ahora no hemos verificado y hasta el momento no hemos encontrado nada que nos ayude a desencadenar la posible explotación de VULNSERVER, así que podemos cumplir esta premisa para entrar a la función _Function3 y ver que hay en ella.
Esta función recibe como parámetro el buffer que el usuario ha enviado al binario, también debemos tener en cuenta que al inicio cuando se inicializaron los buffers con malloc en la función LTER su size era de 0x1000.

Stackoverflow Funcion LTER VULNSERVER
Podemos observar que recibimos como parámetro nuestro buffer que es la data que nosotros enviamos, y se hace una copia sin validar el size a nuestro buffer de destino inicializado al inicio de la función LTER con un size de 0x1000 y rellenado con 0.

Buffer destino donde se copiara la data
RESUMEN ANÁLISIS ESTÁTICO
Hemos analizado de forma estática la vulnerabilidad y adicional, hemos comprendido algunas cosas que el software nos juega para poder hacer más complicada la explotación, como la restricción de caracteres.
Entonces para la explotación de este escenario que debemos tener en cuenta:
- Debemos poner el «.» después del nombre de la función, para poder llegar a la función vulnerable.
- Debemos usar en nuestro exploit caracteres <= a 0x7f o jugar con esta resta con el fin de poder evitar que se rompa nuestro exploit.
ANÁLISIS DINÁMICO
Para esta fase voy hacer uso de la herramienta IMMUNITY DEBUGGER, y una plantilla de boofuzz para realizar fuzzing (en el artículo anterior enseñamos como usarlo), ustedes pueden usar la que mejor se ajuste a su necesidad.
DEBUGGEANDO Y ENCONTRANDO EL FALLO
En esta fase lo primero será abrir nuestro binario en immunity debugger y ponerlo a correr, este servicio está corriendo en el puerto 9999.
Realizando fuzzing en la aplicación con boofuzz
Vamos a configurar nuestra plantilla con boofuzz para realizar fuzzing, pero antes veamos como poder interactuar con VULNSERVER, para eso me conecto al servicio y veo su funcionalidad, y pongo el wireshark a la escucha para ver su tráfico.

Uso de la funcion LTER, captura de trafico wireshark
Vemos que la secuencia es conectarse, hacer una petición recibir su respuesta y se mantiene en ese ciclo, importante tener esto en cuenta con el fin de programar bien nuestra plantilla boofuz.

Plantilla base python fuzzer – boofuz
Lanzamos nuestro fuzzer.

Fuzzeando VULNSERVER con boofuz
Vamos a nuestro immunity debugger y nos encontramos con lo siguiente.

Sobreescritura del SEH , exitosamente
Vemos que nuestro programa se ha hecho trizas, nuesro fuffer ha hecho un buen trabajo y ha roto muchas cosas en VULNSERVER, sobreescribimos el SEH y nos muestra adicional en el stack la función strcpy que es la que al parecer ocasionó el problema, también vemos que el parámetro LTER lleva el punto como habiamos visto en el análisis estático, parece que el fuzzer se lo agrego automáticamnete, genial.
PROGRAMANDO NUESTRO EXPLOIT
Bueno, ya comprendimos la vulnerabilidad desde el vector estático y dinámico, ahora empieza la parte más divertida, que debemos tener en cuenta:
- Nuestro exploit debe tener un punto después de nuestro llamado a la función LTER en VULNSERVER.
- Debemos jugar con la restricción de datos >= a 0x7f la cual restará el dato por dicho valor, en nuetsras cargas útiles.
- Debemos buscar un gadget POP – POP -RET .
- Debemos programar nuestra shellcode y a ejecutar código.
Primero que todo vamos a buscar el offset donde podemos controlar SEH, para eso voy armar mi plantilla de exploit base, con un patrón único de 5000 caracteres, alfanumérico.

Plantilla base exploit LTER VULNSERVER
Lanzo mi exploit y obtenemos:

Lanzamiento de exploit contra VULNSERVER
Sobreescribimos SEH como era de esperarse y obtenemos la siguiente string, 0x356f4534 que en ascci sería 4Eo5, chr(0x34) + chr(0x45) + chr(0x6f) + chr(0x35), buscamos en nuestro exploit esta string y hemos enviado 3558 bytes para sobreescribir SEH, de los cuales restamos 8 bytes para controlar SEH y NSEH, quedandonos las cuentas asi:
trash = 3550
trash += NSEH
trash += SEH
trash += «A» * 5000 -len(trash)

Sobreescritura del SEH con patrones unicos
Vamos a modificar nuestro exploit con los cálculos que acabamos de hacer, haber si todo es correcto, enviaré mi fruta con 3550 más 4 bytes A’es y 4 bytes B’es, más el padding para completar 5000 y romper el SEH.

Exploit modificado para controlar SEH con valores definidos
Lanzamos nuestro exploit y tenemos los resultados esperados…

Control Exitoso del SEH
Excelente!!!, ya tenemos el SEH controlado, busquemos nuetsro gadget pop – pop – ret, debemos tener en cuenta que nuestro gadget no debe tener valores mayores a 0x7f, ya que hará la resta sobre ese mismo valor, la opción en estos momentos es trabajar con valores alphanumeric, así que vamos a buscar nuestro gagdget, afortunadamente VULNSERVER mantiene una dll, (essfunc.dll) la cual no tiene ASLR ni protección de SEH, así que podemos usar esa dll para buscar nuestro gadget, yo usaré idasploiter o el mismo immunity debugger para buscar el gadget, con idasploiter pueden ver su uso desde acá.

Busqueda de gadget con immunity debugger

Busqueda de gadget con immunity debugger
Genial, tenemos un gadget que cumple con los requisitos, reemplazemos nuestro SEH con el valor de nuestro gagdget haber que sucede, ponemos un breakpoint en nuestro gadget, corremos el depurador y lanzamos nuevamente el exploit.

Sobreescritura SEH con gadget pop – pop – ret
Una vez pasado la excepción, saltamos a nuestro NSEH que en este caso es 0x43434343.

Salto de Excepcion y ejecucion de NSEH
Necesitamos más espacio para trabajar, 28 bytes no son suficientes para funcionar incluso sin restricciones de caracteres. Podemos dar un salto hacia atrás, con un par de modificaciones.
Para un salto normal hacia atrás, usaríamos los códigos de operación eb XX, donde XX es igual al número de bytes que queremos saltar, menos 1, restados de 255 y convertidos a hexadecimal. Entonces, si queremos retroceder 64 bytes, usaríamos c0, 128 bytes serían 80. No podemos usar ninguno de estos, pero si usamos FF, se convertirá a 80 cuando vulnserver.exe lo haga hex(0xff -0x7f), es una conversión alfanumérica. En lugar de usar eb para un salto corto, podemos usar 77 para un salto corto condicional. Este salto se basa en la bandera cero y la bandera de acarreo no está activada. Podemos asegurarnos de que estén configurados en cero poniendo una operación delante de ellos, como \ x42 que se traduce en INC EDX. Se necesitaría un conjunto de circunstancias muy poco probable para que INC EDX conduzca a la bandera de cero y se establezca la bandera de transporte.
Nuestro gadget se armaria asi:
0: 42 inc edx
1: 42 inc edx
2: 77 ff ja 0x3 => hex(0xff – 0x7f) = 0x80
Establecemos NSEH igual a «\x42\x42\x77\xff» y lo agregamos a la cadena de ataque. Si enviamos esta cadena y la seguimos en el depurador, luego damos el salto, llegamos a unos 127 bytes de código que podemos usar.

Salto negativo exitoso 
Salto negativo exitoso
Podemos observar que la conversión que esperabamos de VULNSERVER al tomar 0xff y restarle 0x7f para tener 0x80 fue correcto.
Ahora que tenemos más espacio, podemos subcodificar valores. La codificación secundaria utiliza valores alfanuméricos e instrucciones SUB para colocar valores específicos que necesitamos en la pila.
El objetivo aquí es volver al principio del búfer para tener más de 3000 bytes para trabajar. Lo primero que debemos hacer es alinear la pila en nuestra área de búfer actual. Para hacer esto, aumentamos ESP en 0x1a48 para colocar ESP justo al final de nuestro búfer actual. Entonces, todo lo que empujemos a la pila se ejecutará. Para hacer esto, introducimos el valor de ESP en la pila, lo introducimos en EAX, lo ajustamos usando la codificación secundaria y luego introducimos el valor de EAX en la pila y lo introducimos en ESP. Ahora, nuestra pila se encuentra al final de nuestro segmento de búfer actual.
25 41 4d 4e 55 and eax,0x554e4d41
25 35 32 31 2a and eax,0x2a313235
54 push esp
58 pop eax

Encoder SUB para ainear la pila
2d 70 70 7c 7c sub eax,0x7c7c7070
2d 20 40 43 43 sub eax,0x43434020
2d 28 35 40 40 sub eax,0x40403528
50 push eax
5c pop esp
Quedando los opcodes finales de la siguiente forma:
«\x25\x41\x4D\x4E\x55\x25\x35\x32\x31\x2A\x54\x58\x2D\x70\x70\x7C\x7C\x2D\x20\x40\x43\x43\x2D\x28\x35\x40\x40\x50\x5C»
Vamos a modificar nuestro exploit y veamos si se ejecutan exitosamente las instruciones dadas.

Exploit modificado con codificacion secundaria stack align

Alineacion de pila usando codificacion secundaria SUB/AND
Genial, todo ha funcionado correctamente, ya tenemos apuntando nuestra pila, donde queremos.
Desde aquí, queremos saltar hacia atrás desde la ubicación de nuestra pila hasta el comienzo de nuestro búfer. Hacemos los cálculos y vemos que necesitamos retroceder 0xdb9, normalmente realizaríamos un salto cercano a FFFFF264, los códigos de operación se traducirían a E9 64F2FFFF debido a la restriccion de caracteres. Tendremos que escribir esto como dos instrucciones en la pila para tener en cuenta el número desigual de bytes, ya que solo podemos escribir 4 bytes a la vez. Debemos poner a cero el registro EAX antes de las instrucciones de subcodificación. Queremos subcodificar los valores 64F2FFFF y E9414141 y empujarlos a la pila en ese orden.
Si no saben como buscar los opcodes de un salto negativo como -0xdb9 pueden usar el assamble de immunity debugger y escribir por ejemplo jmp -0xdb9 y les aparecera algo asi.

uso de assamble immunity para hallar opcodes de salto negativo
Si no quieren encodear a mano, por que consideran que lo aprendieron o ya lo saben, les recomiendo este proyecto que es genial para usar codificación secundaria, llamado Slink, pueden ir a su proyecto en el siguiente enlace, mostraré el ejemplo de la codificación del salto negativo.

Codificacion secundaria usando Slink
Armamos nuestro exploit y lo traceamos para ver si se cumple lo que hemos codificado.

Plantilla exploit modificado con salto negativo
Lo traceamos y obtenemos lo siguiente.

Decodificacion secundaria del salto negativo 
salto negativo exitoso
Ya estamos en el inicio de nuestro buffer y tenemos mucho espacio mas de 3000 bytes para cargar nuestra shellcode ahí, pero antes que nada, debemos alienar la pila y hacerla que apunte a nuestro inicio de shellcode por lo que haremos el mismo ejercicio.
para alinear la pila en mi caso, me he tirado una bolsonada y he restado 0xd80 de mi ESP, para no ir tan lejos, la vi fácil y me fui por ahí, pero no puedo colocar 0x80 por que VULNSERVER me lo restaría así que coloque 0xdff.
54 push esp
58 pop eax
66 2d ff 0d sub ax,0xdff
50 push eax
5c pop esp

alienacion de stack

alineacion de pila para ejecucion de shellcode
Genial ya tenemos la pila alineada y creo que es hora de usar metasploit para generar mi shellcode.
Antes de generarla debo comentarles que si usamos metasploit para generar una shellcode, así sea de tipo alphanumeric, siempre se va hacer uso de unas instrucciones que son caracteres malos para nuestro exploit, por suerte como tenemos apuntando ESP a nuestra shellcode podemos decirle a msfvenom que apunte a ese registro y ahí no usará las instrucciones con caracteres malos.
msfvenom -p windows/meterpreter/bind_tcp LPORT=4444 -f c EXITFUNC=seh BufferRegister=ESP -e x86/alpha_mixed

generacion shellcode con metasploit
Finalmente nuestro exploit queda de la siguiente manera.

Exploit final parte 1 
Exploit final parte 2
ejecutamos nuestro exploit, y vemos el resultado final…

sesion meterpreter abierta exitosamente

CONCLUSIÓN
Finalmente hemos ejecutado código remoto sobre la aplicación, creo que el reto acá está en entender la codificación secundaria, luchar contra los caracteres malos y en alinear la pila, espero que hayan llegado conmigo hasta estas últimas palabras, este artículo estuvo un poco largo pero quizás muy completo, si te gusto el artículo, puedes compartirlo con tus amigos e invitarme un cafe desde aquí.
Agradezco a todos por seguir mis entradas y leer esto que comparto, abrazos.
happy hacking, Cracking and exploiting…
@sasaga92



Deja un comentario