Esta página está traducida automáticamente y pendiente de revisión humana. Una guía de remediación de seguridad que no puedes verificar es una afirmación, así que el original en inglés está a un clic. English.

ADGPO-020: Directiva de ejecución de PowerShell mediante GPO

Plataforma
Active Directory
Categoría
AD Group Policy
Severidad
Medium
Pilar de Zero Trust
Governance (peso 1)
Fixtures de referencia
2
Cobertura de ramas
Observada: los fixtures prueban los veredictos que ejercitan
Procedencia
baseline

Qué comprueba

La directiva de ejecución de PowerShell controla qué scripts pueden ejecutarse en un sistema. Aunque la directiva de ejecución no es un límite de seguridad, establecerla en Unrestricted o Bypass mediante GPO elimina una capa de defensa y facilita a los atacantes la ejecución de scripts maliciosos sin avisos al usuario

Por qué importa

Microsoft is explicit that execution policy is not a security control: it is a usability fence designed to prevent a user from running a script by accident. Five documented bypasses exist on every modern Windows host: powershell.exe -ExecutionPolicy Bypass, powershell.exe -Command (passing the script body directly), reading the file with Get-Content and piping to Invoke-Expression, base64-encoded -EncodedCommand payloads, and loading PowerShell through System.Management.Automation.dll from a custom host (the technique behind PowerPick and unmanaged PowerShell runners). An attacker who already has code execution on the host can run any script regardless of the policy setting. The policy still matters for two reasons. First, it is a tripwire for interactive and semi-interactive vectors: a user double-clicking a .ps1 from an HTML smuggling drop, a macro-launched Wscript-to-PowerShell chain, or a LOLBin-launched script will succeed silently on a Bypass host and fail with a console prompt or block on a RemoteSigned/AllSigned host. Second, the value pushed by GPO is consumed by every PowerShell session that does not explicitly override it, including scheduled tasks, login scripts, software-deployment wrappers, and third-party PowerShell hosts that do not pass -ExecutionPolicy. Setting Unrestricted or Bypass via GPO across an OU turns thousands of endpoints into environments where every PowerShell child process inherits a permissive default, every Internet-zone script runs without the AlternateDataStream MOTW warning, and every signed-script enforcement requirement built into vendor tooling is silently nullified. The blast radius compounds when the GPO is linked to the Domain Controllers OU or any Tier-0 OU: a Bypass policy on a DC means any script staged through SYSVOL, a write-able share, or a scheduled-task creation path runs without challenge in LSASS context.

Ruta de ataque

1. Reconnaissance: the attacker, holding any authenticated domain user, enumerates GPOs with Get-DomainGPO (PowerView), parses the Registry.pol files inside SYSVOL under \\domain\SYSVOL\<domain>\Policies\{GUID}\Machine\Registry.pol, and reads the ExecutionPolicy and EnableScripts values directly. BloodHound (CollectionMethod GPOLocalGroup) shows which OUs each GPO is linked to. 2. Target selection: the attacker prioritizes GPOs that set ExecutionPolicy to Unrestricted or Bypass and are linked to OUs containing workstations, jump servers, or domain controllers. A Bypass policy on the workstations OU means every endpoint is one .ps1 drop away from execution. 3. Initial access: the attacker delivers a .ps1 payload through a phishing attachment that uses HTML smuggling to write the file to %TEMP%, through a watering-hole download that lands the file with the MOTW Internet-zone marker, or through a SharePoint/OneDrive sync that ignores zone identifiers. On a Bypass host the script runs on double-click. On a Restricted host the user sees a console prompt; on a RemoteSigned host the Internet-zone marker blocks execution; on an AllSigned host the script is blocked unless signed by a trusted publisher. 4. Lateral movement: once the attacker has code execution on one host, they enumerate other hosts in the same OU and reuse the same .ps1 payload. WMI, WinRM, and PSExec all invoke powershell.exe with the GPO-resolved default policy on the remote host, so a Bypass policy in scope on the target means no -ExecutionPolicy flag is required and no Defender heuristic for "explicit policy override" fires. 5. Tradecraft: with Bypass in scope the attacker does not need to call powershell.exe -ExecutionPolicy Bypass, which is a high-signal pattern that EDR vendors alert on. The attacker can call powershell.exe -File script.ps1 or powershell.exe -Command ". \\share\script.ps1" and inherit the GPO default. This reduces detection surface in environments that rely on commandline analytics. 6. Persistence: the attacker drops a .ps1 in a writeable startup folder or registers a scheduled task that invokes powershell.exe -File. With Bypass in the GPO, the task runs at every logon without any policy-related event in the PowerShell operational log or in Defender telemetry. 7. Tier-0 escalation: if the same GPO is linked to the Domain Controllers OU, the attacker who reaches a DC (via a separate path: print spooler, ADCS ESC, weak ACL) can run unsigned PowerShell directly in LSASS context, including DSInternals, Mimikatz wrappers, and DCSync wrappers, without ever toggling the policy or leaving an artifact in the GPO change log.

Cómo lo evalúa Guerrilla

Guerrilla loads the GroupPolicy and ActiveDirectory modules, calls Get-GPO -All -Domain $env:USERDNSDOMAIN, then for each GPO calls Get-GPRegistryValue -Guid $gpo.Id -Key "HKLM\Software\Policies\Microsoft\Windows\PowerShell" -ErrorAction SilentlyContinue and the corresponding HKCU path. Each returned value pair is normalized into an ExecutionPolicy state (Restricted, AllSigned, RemoteSigned, Unrestricted, Bypass, Undefined) and an EnableScripts boolean. Linked scopes are resolved via Get-ADOrganizationalUnit -LDAPFilter "(gPLink=*$($gpo.Id)*)" and Get-ADObject -SearchBase "CN=Sites,CN=Configuration,$($domain.DistinguishedName)" -LDAPFilter "(gPLink=*$($gpo.Id)*)" plus the gPLink on the domain root. The check classifies each GPO as Pass, Fail, or Informational. Fail conditions: ExecutionPolicy in {Unrestricted, Bypass}; EnableScripts = 1 with ExecutionPolicy undefined; HKCU policy weaker than HKLM policy in the same scope; any of the above in a scope that includes Domain Controllers or Tier-0 OUs (severity escalated). Output rows include DisplayName, Id, Scope (Computer/User), ExecutionPolicy, EnableScripts, LinkedScopes, TierZeroLinked (bool), CoConfiguredLogging (bool: whether ScriptBlock/Module logging is also set), and Notes. The check also enumerates the resolved policy on the auditing host with Get-ExecutionPolicy -List as a sanity check that the GPO state matches what the Group Policy engine actually applies.

Valor recomendado

Directiva de ejecución de PowerShell establecida en AllSigned o RemoteSigned mediante GPO; no establecida en Unrestricted ni Bypass

Remediación

Revise las configuraciones de GPO en Configuración del equipo > Plantillas administrativas > Componentes de Windows > Windows PowerShell > Activar la ejecución de scripts. Establezca la directiva de ejecución en AllSigned para entornos de alta seguridad o RemoteSigned para entornos estándar. Implemente la firma de código para los scripts de PowerShell autorizados. Evite establecer Bypass o Unrestricted mediante GPO.

Veredictos probados con fixtures

Cada veredicto de esta tabla está probado por un fixture de referencia en la suite de pruebas que valida el módulo. La tabla se deriva de la última ejecución en verde; no puede editarse a mano.

Escenarios de veredicto de ADGPO-020
EscenarioVeredicto esperado
informationalWARN
throttledNot Assessed

Mapeos a marcos de referencia

NIST SP 800-53
CM-6, CM-7, SI-7
MITRE ATT&CK
T1059.001, T1484.001