Otro bypass de UAC en 2018: Mocking Trusted Directory
Llegando al final del año nos encontramos con un nuevo bypass del sistema UAC (User Account Control) de Windows. El investigador David Wells ha publicado un nuevo método para obtener un bypass de UAC en un detallado artículo que os recomiendo que echéis un ojo, por la sencillez y por su forma didáctica de explicarlo. Además, David Wells ha publicado una PoC (Prueba de Concepto) en Github.
También hay que comentar que, aunque esto se ha publicado hace unos pocos días, el proyecto UACME ya dispone del bypass implementado por si quieres echarle un ojo. Así que, en el artículo de hoy quería comentar cómo funciona este nuevo bypass y cómo se puede llevar a cabo su aprovechamiento en un proyecto de Ethical Hacking.
Pronto incorporaremos la PoC publicada en GitHub por David Wells a proyectos como UAC-A-Mola o ibombshell, herramientas que han estado y que estarán en el Arsenal de Black Hat.
Como en otros tantos artículos y charlas sobre el UAC hemos comentado, para que existe un bypass de UAC se debe dar algunas circunstancias, por ejemplo, que el usuario que lanza el proceso pertenezca al grupo de administradores. A modo de recopilación dejo algunos requisitos que tenemos a la hora de poder hacer un bypass de UAC:
David Wells detalla el proceso de elevación
Quizá es una de las partes más gráficas que he encontrado para explicar este proceso. Me ha parecido realmente interesante y por ello lo expongo aquí. Como decíamos en el primer paso, el AutoElevate debe estar puesto a true. En otras palabras, cuando una petición de elevación es generada se produce una llamada RPC a appinfo.dll. En esta llamada se pasa como argumento la ruta al ejecutable con el que se quiere hacer el bypass del UAC.
El servicio leerá el Manifest del binario para obtener el valor potencial de la directiva AutoElevate, si ella existe, lógicamente. Si el valor True es encontrado se considera que es un ejecutable que puede autoelevarse sin sacar el UAC por pantalla. Decir que hay una excepción a esto y es que, si el binario se encuentra en la lista blanca de EXEs, también se considera una ejecución autoelevable, por lo que se chequea si el binario se encuentra en esa lista blanca.
La segunda condición es el chequeo de la firma del binario. Para ello se utiliza wintrust!WTGetSignatureInfo. Esto hace que un potencial atacante no pueda modificar el Manifest de un binario y coloque el Autoelevate a True y engañe al paso anterior. En este punto se comprueba la firma del binario y que éste no ha sido modificado.
El paso tres, o la tercera condición, es que el binario en el que nos apoyaremos para el bypass se ejecuta desde un directorio de confianza. Por ejemplo, C:\Windows\System32, el cuál es el directorio que siempre hemos probado y utilizado para el bypass de UAC.
¿En qué consiste el nuevo bypass de UAC?
Lo curioso de este nuevo bypass es que se utiliza la tercera condición para engañar a una función del sistema que debe validar la ruta como un directorio de confianza. En otras palabras, vamos a crear una ruta en el sistema que se parece, al menos visualmente, a \Windows\System32, pero no será dicha ruta si no que será \Windows \System32. Nótese el espacio que hay detrás de la carpeta Windows.
Por supuesto, no será tan sencillo como crear la carpeta “\Windows \” con el espacio desde el proceso explorer.exe, eso no funcionará, pero si utilizando unas funciones dedicadas a crear directorios y que nos generará dicha carpeta en la raíz del disco.
La DLL Appinfo.dll utiliza RtlPrefixUnicodeString para ver si la ruta al ejecutable comienza por “C:\Windows\System32”. El “truco” está en que si creamos un directorio “C:\Windows \System32” no podemos llevarlo a cabo contra RtlPrefixUnicodeString, pero con la API de CreateDirectory se puede hacer el bypass y se crea en el sistema de archivos, incluido Windows 10.
El resultado en el explorador de archivos se puede incluso ver. Para poder copiar archivos a esta nueva ruta se puede utilizar [System.io.file]::Copy(..). Como veréis con el explorer también se pueden ver dos carpetas “Windows” sobre la raíz.
Solo que en un System32 no hay nada, ese es el directorio Windows falso. Por otro lado, en la prueba de concepto de David Wells se puede ver el código en otro lenguaje. Se recomienda probarla.
Cuando se intente ejecutar el binario que hay dentro de “C:\Windows \System32\” se enviará a la API en appinfo.dll antes de realizar el chequeo de directorio de confianza. Este hecho es importante, ya que provocará el bypass.
¿Cómo se provoca este bypass?
La ruta es enviada a la función GetLongPathNameW, el cual convierte la ruta a “C:\Windows\System32\binario.exe”. Nótese que el espacio es eliminado. En este punto tenemos el bypass para que el sistema piense que es una ruta de confianza. Ahora se hace uso de RtlPrefixUnicodeString para el resto de la rutina de elevación que se ha comentado anteriormente.
El investigador David Wells publicó una imagen donde deja muy claro el proceso de este potente y curioso bypass que abre puertas a otros binarios débiles a esta técnica.
Seguramente, pronto veamos una versión de este código para Metasploit y otras herramientas. Nosotros trabajaremos para llevarlo a UAC-A-Mola e ibombshell. Sin duda una debilidad en la configuración por defecto de Windows que ayuda, y mucho, en los procesos de Ethical Hacking.
Autor: Pablo González Pérez (@pablogonzalezpe), escritor de los libros "Metasploit para Pentesters", "Hacking con Metasploit: Advance Pentesting" "Hacking Windows", "Ethical Hacking", "Got Root" y “Pentesting con Powershell”, Microsoft MVP en Seguridad y Security Researcher en el equipo de "Ideas Locas" de la unidad CDO de Telefónica.
Figura 1: Otro bypass de UAC en 2018: Mocking Trusted Directory |
También hay que comentar que, aunque esto se ha publicado hace unos pocos días, el proyecto UACME ya dispone del bypass implementado por si quieres echarle un ojo. Así que, en el artículo de hoy quería comentar cómo funciona este nuevo bypass y cómo se puede llevar a cabo su aprovechamiento en un proyecto de Ethical Hacking.
Figura 2: Artículo sobre "UAC Bypass by Mocking Trusted Directories" |
Pronto incorporaremos la PoC publicada en GitHub por David Wells a proyectos como UAC-A-Mola o ibombshell, herramientas que han estado y que estarán en el Arsenal de Black Hat.
Figura 3: PoC publicada por David Wells en GitHub |
Como en otros tantos artículos y charlas sobre el UAC hemos comentado, para que existe un bypass de UAC se debe dar algunas circunstancias, por ejemplo, que el usuario que lanza el proceso pertenezca al grupo de administradores. A modo de recopilación dejo algunos requisitos que tenemos a la hora de poder hacer un bypass de UAC:
• AutoElevate a true en el manifest del binario.
• Binario firmado por Microsoft.
• Por último, y aunque no lo hemos comentado en algunas ocasiones, el directorio desde el que se ejecuta el binario debe ser un directorio de confianza o ‘trusted directory’.El objetivo es conseguir que nuestro código, DLL, binario, etcétera, sea ejecutado en un contexto de integridad alto sin que, para ello, el UAC muestre el mensaje. De esto ya hemos hablado mucho en el último año y medio.
David Wells detalla el proceso de elevación
Quizá es una de las partes más gráficas que he encontrado para explicar este proceso. Me ha parecido realmente interesante y por ello lo expongo aquí. Como decíamos en el primer paso, el AutoElevate debe estar puesto a true. En otras palabras, cuando una petición de elevación es generada se produce una llamada RPC a appinfo.dll. En esta llamada se pasa como argumento la ruta al ejecutable con el que se quiere hacer el bypass del UAC.
El servicio leerá el Manifest del binario para obtener el valor potencial de la directiva AutoElevate, si ella existe, lógicamente. Si el valor True es encontrado se considera que es un ejecutable que puede autoelevarse sin sacar el UAC por pantalla. Decir que hay una excepción a esto y es que, si el binario se encuentra en la lista blanca de EXEs, también se considera una ejecución autoelevable, por lo que se chequea si el binario se encuentra en esa lista blanca.
La segunda condición es el chequeo de la firma del binario. Para ello se utiliza wintrust!WTGetSignatureInfo. Esto hace que un potencial atacante no pueda modificar el Manifest de un binario y coloque el Autoelevate a True y engañe al paso anterior. En este punto se comprueba la firma del binario y que éste no ha sido modificado.
El paso tres, o la tercera condición, es que el binario en el que nos apoyaremos para el bypass se ejecuta desde un directorio de confianza. Por ejemplo, C:\Windows\System32, el cuál es el directorio que siempre hemos probado y utilizado para el bypass de UAC.
¿En qué consiste el nuevo bypass de UAC?
Lo curioso de este nuevo bypass es que se utiliza la tercera condición para engañar a una función del sistema que debe validar la ruta como un directorio de confianza. En otras palabras, vamos a crear una ruta en el sistema que se parece, al menos visualmente, a \Windows\System32, pero no será dicha ruta si no que será \Windows \System32. Nótese el espacio que hay detrás de la carpeta Windows.
Por supuesto, no será tan sencillo como crear la carpeta “\Windows \” con el espacio desde el proceso explorer.exe, eso no funcionará, pero si utilizando unas funciones dedicadas a crear directorios y que nos generará dicha carpeta en la raíz del disco.
La DLL Appinfo.dll utiliza RtlPrefixUnicodeString para ver si la ruta al ejecutable comienza por “C:\Windows\System32”. El “truco” está en que si creamos un directorio “C:\Windows \System32” no podemos llevarlo a cabo contra RtlPrefixUnicodeString, pero con la API de CreateDirectory se puede hacer el bypass y se crea en el sistema de archivos, incluido Windows 10.
Figura 4: Creación del directorio con la AP de CreateDirectory en Windows 10 |
El resultado en el explorador de archivos se puede incluso ver. Para poder copiar archivos a esta nueva ruta se puede utilizar [System.io.file]::Copy(..). Como veréis con el explorer también se pueden ver dos carpetas “Windows” sobre la raíz.
Figura 5: Dos carpetas Windows en el sistema |
Solo que en un System32 no hay nada, ese es el directorio Windows falso. Por otro lado, en la prueba de concepto de David Wells se puede ver el código en otro lenguaje. Se recomienda probarla.
Figura 6: Creación de directorios de confianza falsos con API CreateDirectoryW en la PoC |
Cuando se intente ejecutar el binario que hay dentro de “C:\Windows \System32\” se enviará a la API en appinfo.dll antes de realizar el chequeo de directorio de confianza. Este hecho es importante, ya que provocará el bypass.
¿Cómo se provoca este bypass?
La ruta es enviada a la función GetLongPathNameW, el cual convierte la ruta a “C:\Windows\System32\binario.exe”. Nótese que el espacio es eliminado. En este punto tenemos el bypass para que el sistema piense que es una ruta de confianza. Ahora se hace uso de RtlPrefixUnicodeString para el resto de la rutina de elevación que se ha comentado anteriormente.
El investigador David Wells publicó una imagen donde deja muy claro el proceso de este potente y curioso bypass que abre puertas a otros binarios débiles a esta técnica.
Figura 7: Esquema de funcionamiento explicado por David Wells |
Seguramente, pronto veamos una versión de este código para Metasploit y otras herramientas. Nosotros trabajaremos para llevarlo a UAC-A-Mola e ibombshell. Sin duda una debilidad en la configuración por defecto de Windows que ayuda, y mucho, en los procesos de Ethical Hacking.
Autor: Pablo González Pérez (@pablogonzalezpe), escritor de los libros "Metasploit para Pentesters", "Hacking con Metasploit: Advance Pentesting" "Hacking Windows", "Ethical Hacking", "Got Root" y “Pentesting con Powershell”, Microsoft MVP en Seguridad y Security Researcher en el equipo de "Ideas Locas" de la unidad CDO de Telefónica.
No hay comentarios:
Publicar un comentario