lunes, 24 de julio de 2017

Bypass UAC en Windows 7 usando DLL Hijacking con .NET Code Profiler

Los bypasses sobre UAC están cayendo casi semanalmente. Es cierto que Microsoft no los considera una vulnerabilidad, pero pueden ayudar en un pentest bastante, ya que, si el proceso comprometido pertenece a un usuario del grupo administrador, tendríamos una puerta abierta a lograr ejecutar código con el máximo privilegio. En esta ocasión, el bypass de UAC ha sido descubierto por el investigador Stefan Kanthak.


Como el propio investigador comenta en su publicación realizada a través de Seclists, todas las versiones de .NET Framework pueden cargar un objeto COM como Code Profiler, el cual se habilita a través de dos variables de entorno. Como indica Microsoft, un Profiler DLL es una librería de vínculo dinámica no administrada, la cual se ejecuta sin restricciones de código gestionado. La única limitación sobre el Profiler DLL la impone el sistema operativo sobre el usuario que ejecuta la aplicación.

Figura 2: Publicación del Bypass UAC en Seclist

Cuando las comprobaciones de variables de entorno existen se resuelven de forma satisfactoria, se instancia el generador de perfiles. Al final, la técnica utilizada por el investigador ha sido un DLL Hijack de una forma interesante. La técnica consiste en habilitar las variables de entorno COR_ENABLE_PROFILING y COR_PROFILER.

Figura 3: Detalles en el proyecto UACME

Sabiendo que eventvwr.msc y secpol.msc están escritas en .NET y en su ejecución, si las variables de entorno anteriores están habilitadas, harán uso de código no administrado, se puede lograr un bypass de UAC. La técnica ha sido validada en Windows 7


¿Cómo conseguimos el bypass de UAC?

Realmente es sencillo. Lo primero es habilitar las variables de entorno. COR_ENABLE_PROFILING a 1, para habilitarla. COR_PROFILER deberá apuntar a una clave de registro, un CLSID. En otras palabras, el CLSID se encontrará en HKCU\Software\Classes\CLSID\[ID del CLSID]. El ID del CLSID da igual el que se ponga, por ejemplo 44444444-4444-4444-4444-444444444444. Ahora, hay que pensar que el valor de clave CLSID que tenemos que crear debe apuntar a una ruta dónde tendremos el código, en forma de DLL, que se quiere ejecutar.

Figura 4: Creación del CLSID apuntando a la DLL que usará COR_PROFILER 

Cuando desde una cmd.exe ejecutemos "start mmc.exe eventvwr.msc", la Microsoft Management Console se arrancará y cargará el complemento del visor de eventos. Como las variables de entorno, mencionadas anteriormente están habilitadas, se utilizará código no administrador, la cual será nuestra DLL. Como la instrucción "mmc.exe eventvwr.msc" se ejecuta en un contexto de integridad alto y ésta es la que carga el código de la DLL, éste también se ejecutará con el mismo nivel de integridad alto, realizando de este modo el bypass de UAC.


PoC: Consiguiendo el bypass

Antes de empezar, vamos a resumir el proceso con este pseudocódigo:
1. Configurar variables de entorno: 
a. Set COR_ENABLE_PROFILING=1
b. Set COR_PROFILER={XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
2. Crear la DLL con código que nos interese ejecutar. En este caso, se puede utilizar msfvenom de la siguiente manera:
msfvenom –p [payload] –b ‘\x00\x0d\x0a’ –f dll –o [ruta salida DLL]. 
3. Crear el hive del registro para apuntar a la DLL que nos interese, que la hemos creado en el paso anterior. En la imagen se puede ver un ejemplo de lo que tenemos que crear, lo cual, lógicamente, lo podríamos crear por línea de comandos. 
4. Cuando se ejecuta una aplicación .NET, la cual detecta que tiene la variable de entorno COR_ENABLE_PROFILING habilitado mirará qué valor tiene la variable COR_PROFILER. Al recoger el valor de la segunda variable de entorno el proceso consulta la ruta HKCU\Software\Classes\CLSID y comprueba si la clave existe.
Figura 5: Como la hemos creado antes, existe y devuelve el valor de la clave
5. La DLL se ejecutará por el proceso que lo invoque. 
6. El truco está en que si es un proceso con integridad alta quién consulta estos valores, tendremos código nuestro ejecutándose con privilegio. Por esta razón, se deberá ejecutar start mmc.exe eventvwr.msc para lograr la ejecución de código privilegiada.
Cuando lanzamos la instrucción "start mmc.exe eventvwr.msc" encontramos un messagebox en el que se nos indica el nivel de integridad del proceso y se abre una cmd.exe. Este interfaz de comandos ya se está ejecutando con un privilegio alto, debido a que es el eventvwr.msc realmente el que la ha invocado.

Figura 6: Interfaz de comandos ejecutado con nivel de integridad alto

En la siguiente imagen, se puede ver el contexto de integridad en el que se están ejecutando los procesos. Como se puede ver, tenemos una cmd.exe con integridad media, esta es desde dónde desembocamos todo el proceso.

Figura 7: Nivel de Integridad "High" por haber autoelevado el mmc.exe

Después vemos el mmc.exe con integridad alta y sin notificar UAC, ya que el eventvwr está autoelevado y, por último, tenemos una nueva cmd.exe creada por mmc.exe con integridad alta. Aquí tenemos el bypass UAC. Por último, os dejamos un video para que veáis el proceso en funcionamiento y cómo funciona este bypass de UAC.

Figura 8: PoC en vídeo de Bypass UAC usando DDL Hijacking con .NET Code Profiler

Hay que indicar que el bypass de UAC podría ser aprovechado a través, por ejemplo, de una sesión de Meterpreter y lograr conseguir ejecutar código en un contexto elevado en proyecto de Ethical Hacking. Sin duda, interesante técnica y de sencilla explotación.