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.
![]() |
Figura 1: ByPass UAC en Windows 7 usando DLL Hijacking con .NET Code Profiler |
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, como se puede ver
en el proyecto UACMe.¿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.