INTRODUCCIÓN
Hola a todos el día de hoy, vamos hablar sobre una vulnerabilidad de día cero que identifiqué sobre un producto de la empresa webgate, en uno de sus productos pro llamado Control Center Pro v6.2.9, este producto esta destinado hacer usado para conectar las cámaras de tipo videovigilancia y dvr en red, que ofrece está misma empresa, o en su defecto otras que se puedan conectar de la misma forma, y otra infinidad de cosas.
¿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), lucharemos con alguna restricción de badchars o caracteres malos y ejecutaremos 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)
- Windows 10 PRO N o XP SP3
- El ejecutable de Control Center Pro v6.2.9
Todo esto pueden encontrarlo desde mi repositorio, aquí.
REVERSANDO Y ENCONTRANDO EL FALLO
Lo primero será instalar el programa y buscar el formulario de creación de usuarios ubicada en Menu -> settings -> User Account -> Add.

Identificación de formulario vulnerable
Para probar si es vulnerable voy hacer algo muy sencillo, voy a generar con python una cadena de 40000 mil A’es y la pegaré en el campo username/Nombre, colocaré en id de usuario el valor 2, contraseña el valor 3 y confirmar contraseña tambien 3.

generación de A’es con lenguaje python
Una vez realizada la acción mencionada anteriormente vemos que nuestro software se crasheo y si analizamos los registros y el SEH vemos cosas interesantes.

Crasheo del programa y escritura de EIP 
Sobreescritura del SEH
Efectivamente, podemos ver que hemos sobreescrito el SEH que es mucho mejor para crear un exploit más seguro, pasemos a buscar la zona donde esta el fallo.
Aca podemos hacer uso de la función TimeTravel de WindbgPreview o ir a las strings y buscar información que haga referencia a agregar usuario o actualizar, para mi caso si se animan a que les enseñe como usar el Time Travel de WindbgPreview pueden dejar un comentario y en el próximo tutorial de seguro lo haremos, mientras tanto iré a buscar referencias a strings o funciones que concuerden con el módulo del fallo, crear usuario.
En mi caso voy a usar IDA para el ejercicio estático y veo que en el módulo imports si escribo UpdateData encuentro lo siguiente:

Busqueda de funcion vulnerable UpdateData(int)
Si damos doble click y buscamos las referencias vemos que hay demasiadas, hay momentos en que usar el TimeTravel es lo mejor para estos casos.

Identificación de referencias multiples a función UpdateData(int)
Lo que yo hice fue tracear todas las llamadas poniendo breakpoints en ellas y pegando mis A’es en el formulario hasta llegar a la siguiente función.

identificación de función vulnerable UpdateData
Una vez identificado esta función pongo un breakpoint en 0x00879A4A y voy a esa llamada y nos encontraremos con lo siguiente.

Inicialización de tamaño de estrucutra 1 
inicialización de tamaños de estructura 2
Antes de que nuestras A’es entren en acción vemos que se inicializa unas estructuras al parecer con unos tamaños fijos, veamos más adelante que se aclara un poco esto.

Obtención del puntero para ubicar la string del id_usuario
Vemos que con la funcion lea obtenemos el puntero hacia la ubicación de la string del id_usuario en donde podemos observar que hay un desplazamiento de ebx+354h, se parece mucho a las inicializaciones que habíamos observado anteriormente.
Lo que voy hacer es crearme una estructura en IDA del tamaño 0x500 y agregaré estos datos para verlos de forma más ordenada, quedandome de la siguiente forma.

creación de estructura y cambio de nombre al puntero user_id
seguimos traceando y vemos que hace lo mismo para los campos de la contraseña en los offsets siguientes:
- ebx+34Ch => password 1
- ebx+350h => password 2

Obtención del puntero para ubicar la string del password 1 y password 2
Reemplazo ese offset por la estructura que creé como en el paso anterior, quedandome ahora asi.

creación de estructura y cambio de nombre al puntero password 1 y password 2
Seguimos traceando y vemos lo siguiente, se obtiene el puntero a la string user_id, se llama a la función GetBuffer y se guarda en ECX el tamaño de la string, en mi caso 3, en EAX queda guardado el puntero a la string user_id.

proceso con string user_id
El puntero hacia el string user_id, en EAX mi caso es: 0x0B21FFA8
El puntero de preparación para apuntar a mi buffer destino en EDX es: 0x083BE134
Luego podemos ver que hay una operación matemática sub eax, edx que al final se resume en copiar mi string_id byte a byte en :
- mov [edx+eax], cl
si hacemos las cuentas en python de la siguiente forma:
- hex(0x083BE134 – 0x0B21FFA8) = -0x2e61e74 luego hex(0x0b21ffa8 + (-0x2e61e74)) = 0x83be134
Que me parece una barbarie hacer esto por que si se fijan es el mismo valor que esta en EDX donde al final se copiará nuestra string user_id.

Copia de string user_id a dirección destino en la estructura
Luego podemos observar que toma el puntero de inicio de la contraseña 2 y lo guarda en ECX, y hace lo mismo con un offset de la misma estructura [ebx+0D8h] y lo guarda en EDX, por suerte creamos una estructura anteriormente lo cual nos va a servir para no perdernos.
En las siguientes imagenes podemos apreciar las distancias que hay entre user_id y password es de 0x40, algo muy similar a la función de inicialización de las estructuras.

Distancia entre user_id y password dentro de la estructura 
Tamaño inicializado para una parte de la estructura
Continuamos traceando, y vemos el mismo proceso para el campo correo

Distancia entre password y mail dentro de la estructura 
Tamaño inicializado para una parte de la estructura
Bueno ya podemos ir sacando conclusiones de aca en adelante, nos faltaria el campo username y description, si sacamos conclusiones vemos que no se valida los tamaño de lo que insertemos en los campos en ningun lado, y si pegamos muchas A’es en nuestro campo username por ejemplo, romperia los datos del siguiente campo por lo cual si se operara con lo que sigue lo unico que encontraran seran A’es, pero mejor veamoslo y no concluyamos todavia.

Desbordamiento y sobre escritura de datos en la estructura 
Sobreescritura de datos
Vemos que el puntero destino para los datos del username esta encima del mail, osea siguiendo el orden del formulario, pero como sabemos que no hay una restriccion de copia en estas areas lo que siga despues del area de username sera sobre escrito con mis A’es asi que ya sabemos de donde y como se desencadena la vulnerabilidad.
PROGRAMANDO NUESTRO EXPLOIT
Bueno, ya comprendimos la vulnerabilidad desde el vector estático y dinámico, ahora empieza la parte más divertida, la creacion de nuestro exploit, vamos hacer lo siguiente:
- Crear nuestra plantilla base en python que genere una cadena de 40000 caracteres, las cuales las 1000 primeras seran un patron para ubicar la porcion exacta que sobreescribe los registros, y el SEH
- Esta informacion generada la exportaremos a un archivo donde luego copiaremos la data a nuestro campo y veremos su comportamiento.

Plantilla base exploit para Control Center pro v6.2.9
Ejecutamos nuestro exploit y abrimos el contenido de nuestro archivo generado.

Patron generado por nuestro exploit
Voy a correr mi programa, y luego voy a pegar mi payload en el campo username y veamos que sucede…

Sobreescritura del SEH con cadena 2Aw3
Hemos sobre escrito el SEH con la cadena 2Aw3 si buscamos esta cadena en nuestro archivo generado vemos que corresponde al tamaño 672, sabemos que la lista del SEH es de 8 bytes si lo restamos nos quedaria: (672-8 = 664) luego ya sabemos el offset para nuestro exploit, vamos a modificar nuestra plantilla base, quedandonos de la siguiente forma.

Modificación exploit con datos NSEH y SEH
Al ejecutar el exploit y copiar los datos generados obtenemos lo siguiente, sobreescribiendo exitosamente la cadena SEH con nuestros datos.

Sobreescritura del SEH con nuestros datos preparados
Algo muy importante es verificar los caracteres malos o «bad chars» que no debe contener mi exploit, ya que esto cortaria el flujo de nuestro payload, lo que harémos sera generar un payload que valla desde 0x01 a 0xFF y la pegaremos en mi exploit como si fuera mi shellcode y veremos si existen badchars, normalmente en todo exploit se descartan los bytes 0x00, 0x0a, 0x0d, 0xff, por ser terminadores de string, pero no todos los casos son asi, por eso voy a probarlos todos excepto el 0x00 para ver que bytes puedo utilizar, quedando nuestra plantilla de exploit de la siguiente manera.

Plantilla exploit para busqueda de badchars 
Identificación bad char 0x0a
Al copiar mi payload en el campo username podemos ver que el registro ESI apunta a parte de mi exploit, le doy jump in hex en mi IDA, si analizamos podemos identificar que el byte 0x0a es un badchar ya que venia la cadena de flujo desde 0x01 y despues de 0x09 vemos que sigue un 0x00, eso nos indica que hay algo raro ahi, ademas no continua nuestro flujo, eliminemos 0x0a de nuestra shellcode y ejecutemos nuevamente.

Identificación bad char 0x0d
vemos que 0x0d tambien es un bad char, asi que lo quitamos de nuestro shellcode en el exploit, y lo volvemos a lanzar.

Identificación de bad chars >= 0x80
En la imagen anterior podemos apreciar que no podemos usar bytes >= a 0x80 ya que los convierte en 0x3f y esto puede tener mucho sentido ya que es un campo de username y caracteres mayores o iguales a 0x80 en la tabla ascii no son caracteres muy comunes para asignarlo como nombres.
En resumen como bad chars o caracteres malos tenemos, 0x00, 0x0a, 0x0d y los mayores o iguales a 0x80.
Esto nos va a limitar un poco con la generacion de shellcode ya que hay demasiados caracteres malos, lo que haremos será trabajar con una shellcode encodeada a traves de metasploit en alpha_mixed y adicionalmente nosotros le diremos en que registro empieza nuestra shellcode, por que si no le indicamos el encoder de metasploit va utilizar unas instrucciones que tienen caracteres que no son permitidos por nuestro programa, pero antes busquemos nuestro gadget pop-pop-ret, ya he explicado mucho como buscarlos asi que no me detendre ahi, para mi caso tengo mi gadget que es el siguiente:
0x0258107E pop edi # pop esi # retn lib_VoiceEngine_dll32.dll 3 8 one-reg, stack edi, esi nonull, ascii
Este gadget cumple con mis requisitos, no contiene ningun caracter malo, armo mi exploit nuevamente y pruebo…

Exploit modificado con mi gadget pop-pop-ret

SEH sobre escrito con nuestro gadget
Podemos ver que el SEH esta sobre escrito con nuestro gadget, le pongo un breakpoint a mi gadget y paso la excepción.

Control del flujo del programa
Vemos que pasando la excepción tomamos control del programa, ahora lo que haremos sera hacer un salto hacia adelante y ver como ejecutar nuestra shellcode, como tenemos la restricción de caracteres malos, vamos a usar un salto condicional como en los articulos pasados, solo que esta vez si sera positivo, para eso usaré el siguiente gadget:
inc edx
inc edx
ja 0xc
Que resumido a opcodes seria: «\x42\x42\x77\x08», estas pequeñas instrucciones cumplen los requisitos de no tener bad chars asi que adelante, mi exploit quedaria asi:

Exploit modificado con salta condicional
Al saltar la excepción nos encontramos con nuestro gadget, funcionando perfectamente.

Salto condicional ejecutado correctamente
Seria fácil para nosotros poner nuestra shellcode seguidamente, pero por los caracteres malos no va hacer posible, veamos la shellcode que genera metasploit encodeada en alpha_mixed sin indicarle un registro, para eso usare el siguiente comando, y analicémosla.
sudo ./msfvenom -p windows/meterpreter/bind_tcp LPORT=4444 -e x86/alpha_mixed EXITFUNC=seh -f c -b ‘\x00\x0a\x0d’

Shellcode encodeada en alpha_mixed con bad chars al inicio
Vemos que al inicio de nuestra shellcode hay unos opcodes que no son soportados por nuestro programa, estas instrucciones iniciales lo que hacen en realidad es buscar el registro hacia donde apunta nuestra shellcode, pero si nosotros usamos el parametro BufferRegister y le indicamos en que registro esta apuntando nuestra shellcode ya no se usaran dichos opcodes y tendremos una shellcode totalmente funcional para nuestro programa, el unico problema es que no hay ningun registro que este apuntando a nuestra shellcode por lo que nos toca preparar un registro y hacerlo que apunte a nuestro shellcode, analicemos nuestros registros.

puntero registro ESP
Vemos que en mi caso el registro ESP apunta a 0x07D2CB10, que esta mas abajo de mi shellcode, si bajamos un poco podemos ver que mi shellcode esta ubicada en la siguiente dirección, en mi caso 0x07D2E350.

Dirección de inicio de shellcode
Entonces si restamos ambas direcciones tenemos una distancia de:
hex(0x07D2CB10 – 0x07D2E350) = ‘-0x1840’
Entonces lo que debemos hacer es sumarle a ESP 0x1840 y quedara apuntando al inicio de mi shellcode, para eso usaremos las siguientes instrucciones, teniendo en cuenta nuevamente la restricción de caracteres, prepararemos el registro ESP en EAX, sumaremos la distancia y lo guardaremos nuevamente en ESP sin usar caracteres malos, en mi ejemplo le sumare 0x1834 con los ajustes de alineación, quedandome asi.
push esp
pop eax
add ax,0x1834
push eax
pop esp
Traducido a opcodes seria: «\x54\x58\x66\x05\x34\x18\x50\x5C»
Modificamos nuevamente nuestro exploit quedando de la siguiente manera.

preparación del registro ESP
Lo ejecutamos y probamos haber que sucede.

ESP apuntando a shellcode exitosamente
Vemos que EAX esta apuntando al inicio de nuestra shellcode asi que ya una vez ejecutado el push eax pop esp, ESP quedaria listo para que apunte a mi shellcode y como EIP esta apuntando al inicio de mi shellcode cuando empiece a ejecutarla ya se ejecutara sin problemas por que le hemos dicho que nuestra shellcode esta apuntando en ESP, genial generemos nuestro shellcode y ejecutemos codigo.

Generación de shellcode alpha_mixed BufferRegister=ESP con metasploit
Una vez generada la shellcode voy a mi exploit lo modifico quedandome de la siguiente forma.

Exploit final parte 1 
Exploit final parte 2
Ejecutamos el exploit, pegamos el contenido en la caja username y tenemos ejecución de codigo de forma exitosa…

Sesión meterpreter abierta exitosamente
AGRADECIMIENTOS
Quiero agradecer al maestro ricardo narvaja de crackslatinos por las sugerencias que me brindó cuando le hice algún par de preguntas sobre el tema, de esta vulnerabilidad.
Tambien al maestro @apuromafo de crackslatinos que saco de su tiempo para ayudarme a entender un poco sobre como funciona la pila y su alineación, que de verdad fue de gran ayuda.
y finalmente al team de @PeruCrackerS.
CONCLUSIÓN
Finalmente hemos ejecutado código remoto sobre la aplicación, despues de un analisis profundo sobre ella, 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