martes, 4 de octubre de 2022

Windows Privesc - Unquoted Service Path – La verdadera Isla de las Tentaciones

Vamos a hacer el símil con el programa, La Isla de las Tentaciones, de la cadena Telecinco.

Los participantes

En un ordenador en el que acabamos de comprometer, hemos descubierto un sistema en el que tenemos acceso con un contexto de usuario o servicio no privilegiado.

Primero de todo como buen curioso y cotilla buscaremos, entre el montón de archivos que tiene la gran mayoría de los usuarios en el escritorio del ordenador alguno que se llame contraseñas.txt. Dado que todos los días no es Reyes y que no siempre se encuentran ficheros interesantes, disponemos a apagar la tele y empezar a enumerar el sistema con la finalidad de escalar los privilegios.

Hay diversas herramientas que enumeran automáticamente distintas formas de escalar privilegios en un sistema Windows. Una de las escaladas más comunes es Unquoted Service Path.

La tentación

Cuando hablamos del concepto "Unquoted Service Path" nos referimos a una vulnerabilidad de escalada de privilegios en sistemas Windows en la que es afectado un servicio. No cualquier servicio, sino aquellos donde el binpath o ruta del binario tenga espacios (' ') y no esté entre comillas (' " ').

Si conseguimos explotar la vulnerabilidad conseguiremos elevar nuestra sesión al contexto del usuario que esté corriendo el servicio, el cual normalmente es NT AUTHORITY\SYSTEM.

La vulnerabilidad es causada en la función CreateProcessA de la librería de Windows processthreadsapi.h


Sin entrar en detalle cabe recalcar el parámetro lpApplicationName. Dicho parámetro contiene el módulo que ejecutará como la ruta completa de una aplicación. Si dicho parámetro es una cadena de texto muy larga que contiene espacios y no está entre comillas, el nombre del archivo que se ejecutará será en orden de izquierda a derecha hasta llegar al espacio y añadirá la extensión ".exe" al final.

Una forma de entenderlo de manera clara es con un ejemplo. Para ellos pondremos el caso que un servicio tiene la siguiente ruta del binario:

-    C:\Program Files\Service Example\Vuln Services\ISEC Labs.exe

El orden que la función CreateProcessA utilizará a la hora de buscar el binario será el siguiente:

  1. C:\Program.exe
  2. C:\Program Files\Service.exe
  3. C:\Program Files\Service Example\Vuln.exe
  4. C:\Program Files\Service Example\Vuln Services\ISEC.exe
  5. C:\Program Files\Service Example\Vuln Services\ISEC Labs.exe

¿Cuándo será explotable dicha vulnerabilidad?

Pues podremos explotarla si tenemos permisos de escritura en alguna de las carpetas mencionadas desde el contexto del usuario actual.

Montando nuestra Isla

Una vez explicado el concepto vamos a montar nuestro mini laboratorio. Primero como no, necesitaremos una máquina Windows, en mi caso he utilizado una máquina virtual Windows 10.

Además, necesitaremos crear un servicio vulnerable. Para ello he decidido crear un Windows Service en blanco, es decir que no hace absolutamente nada, ni un print, desde Visual Studio.

Para ello crearemos un nuevo proyecto de tipo Servicio de Windows (.NET Framework).


Una vez creado en el panel de Explorador de soluciones situado en el extremo derecho inferior de la ventana, veremos que hay un fichero llamado Service1.cs.


Presionamos doble clic y se abrirá una pestaña de diseño del Service1.cs. Simplemente desde esa ventana compilamos el proyecto.

Compilar -> Compilar solución


Una vez compilado correctamente y sin errores de código se generará el binario ".exe" dentro de la carpeta del proyecto en "./bin/Debug/".


Vamos a alojar nuestro servicio en la carpeta Program Files, que es donde se alojan la gran mayoría de programas de Windows.

En nuestra futura máquina vulnerable creamos la carpeta "My Service" y descargamos nuestro servicio con el nombre "My Service.exe".



Una vez tenemos el binario del servicio, tendremos que crear el servicio. Para ello desde una PowerShell del usuario Administrador crearemos el servicio especificando el nombre y la ruta del binario. Además, configuraremos nuestro servicio como AutoStart para que cada vez que se encienda el ordenador el servicio arranque automáticamente, configuración muy común en la gran mayoría de servicios.



Finalmente daremos permisos de escritura a la carpeta C:\Program Files\My Service\ a todos los usuarios del sistema.


Una vez montado el laboratorio vamos a ensuciarnos las manos y explotarlo.

Identificación

Empezaremos enumerando todos los servicios, mostrando el nombre, la del binario y el tipo de startup.


Como Podemos observar nos salen muchísimos resultados, muchos de svchost.exe. Vamos a filtrarlos desde PowerShell para tener unos resultados más concisos.


Ya aparecen menos resultados, ahora también filtraremos y mostraremos sólo los que tengan espacios y no tengan comillas en la ruta.


Hemos conseguido filtrar la lista hasta los 5 resultados. Se puede observar que el path del binario del servicio MyService tiene espacios y no está entre comillas (quotes), además está configurado como AutoStart, por lo que este servicio es un buen candidato para ser explotable.

C:\Program Files\My Service\My Service.exe

Recordemos que para la explotación de la vulnerabilidad deberemos colocar nuestro binario en una de las carpetas, por lo que habrá que comprobar si tenemos permisos de escritura en alguna de ellas.

Vamos a revisar los permisos con el cmdlet Get-Acl de PowerShell, siguiendo el mismo orden que CreateProcessA tocaría la hora de buscar el binario.

  1. C:\Program.exe
    Deberemos comprobar los permisos en la carpeta raíz de C:\. Como podemos observar sólo disponemos de permisos de lectura y ejecución.




  2. C:\Program Files\My.exe
    Siguiendo el mismo método anterior, comprobaremos los permisos del usuario en la carpeta C:\Program Files. Obtenemos los mismos resultados, es decir únicamente permisos de lectura y ejecución.





  3. C:\Program Files\My Service\
    Finalmente, en la última ruta posible donde podríamos poner nuestro binario, vemos que cualquier usuario del sistema tiene FullControl sobre el directorio.



La Hoguera final

Una vez identificado que el servicio MyService es vulnerable a Unquoted Service Path, y que tenemos permisos de escritura en la carpeta C:\Program Files\My Service\, procederemos a crear un binario malicioso que se ejecutará en contexto de NT AUTHORITY\SYSTEM.

Hay muchas formas de conseguir acceso a un contexto privilegiado desde la ejecución de un binario, una de las más comunes es obtener una reverse shell, pero también podríamos crear un binario que automáticamente al ser ejecutado creara un usuario y lo añadiera al grupo de administradores locales.

En este caso, usaremos metasploit para crear una reverse Shell.


Una vez creado nuestra reverse shell My.exe deberemos descargarla en el sistema vulnerable, para ello decidí enviarla a través de SMB.


Una vez iniciado el server, procedemos a colocar el binario en la ruta deseada.


Finalmente deberemos reiniciar el servicio. No es muy común que un usuario tenga permisos sobre servicios, por lo que deberos esperar a un reinicio del sistema. En el caso de workstations suelen reiniciarse a bastante a menudo, en el caso de los servidores, estos pueden pasar meses sin reiniciarse.

Si disponemos de permisos sobre el binario, se reiniciaría utilizando los cmdlets Stop-Service y Start-Service.


En nuestro caso, el usuario no tiene permisos para parar e iniciar el servicio, por lo que reiniciaremos la máquina.



Después de un reinicio del sistema y dado que el servicio estaba configurado como AutoStart, al arrancar el servicio se ejecutará nuestro binario y nos llegará la reverse Shell a nuestro listener.

Mitigación

Las comillas son la solución, hay que asegurarse que cualquier servicio que tenga espacios en el binary path sea entrecomillado.

Los servicios son guardados en registros, por lo que podemos editarlos desde el propio regedit.

Las claves de registro las podemos encontrar en:

HKLM\SYSTEM\CurrentControlSet\Services

Ahí buscaremos la carpeta del servicio vulnerable y editaremos la clave ImagePath para añadir las comillas a la ruta.

Conclusiones

Para poder explotar dicha vulnerabilidad se han de dar varias condiciones.

  • El servicio debe estar ejecutándose más elevado al actual.
  • La ruta del binario no debe tener comillas, pero sí debe tener espacios.
  • Poseer permisos de escritura en alguna de las carpetas especificadas en el binary path.
  • Y que podamos reiniciar el servicio, normalmente los usuarios no tienen permisos para arrancar o parar servicios, sin embargo, en caso de disponer del AutoStart se podría reiniciar el sistema.

Referencias

  • https://isgovern.com/blog/how-to-fix-the-windows-unquoted-service-path-vulnerability/
  • https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
  • https://pentestlab.blog/2017/03/09/unquoted-service-path/
  • https://medium.com/@SumitVerma101/windows-privilege-escalation-part-1-unquoted-service-path-c7a011a8d8ae

Autor: Mario Valiente - eJPT, OSCP
Dpto. Auditoría