Firmar scripts PowerShell Link to heading

Por motivos de seguridad Windows PowerShell establece unas políticas de ejecución de scripts. Con el fin de evitar posibles ejecuciones de scripts no deseadas. Para poder ejecutar scripts en PowerShell sin problemas, se tendrá que cambiar la política de ejecución (ExecutionPolicy). Por defecto no están definidas y vienen deshabilitadas (Restricted) para todos los scopes.

En un escenario en el que formemos parte de un dominio y deseemos ejecutar scripts PowerShell para la realización de tareas en los endpoints o servidores del parque de equipos de la organización. En la mayoría de los casos me encuentro con la “solución” sencilla y poco idónea. Se trata de aplicar un GPO estableciendo la política de ejecución en modo Unrestricted en las máquinas afectadas. Esto deja vía libre a cualquier usuario para que pueda comprometer la máquina sin ningún tipo de restricción.

Aplicar un hardening en la política de ejecución de scripts PowerShell Link to heading

Lo más correcto en estos casos sería aplicar esta GPO en un modo AllSigned y firmar con un certificado de confianza todos los scripts que vayan a ser ejecutados aplicando así un hardening en la política de ejecución de scripts de forma que sean seguros y confiables en entornos corporativos.

Si disponemos de una PKI de una entidad de certificación ADCS (Active Directory Certificate Services) podremos generar un certificado específico para este fin y propagar este certificado a través de GPO.

Para los siguientes ejemplos usaré un certificado autofirmado.

Modos de la política de ejecución (ExecutionPolicy):

ModoComportamiento
RestrictedBloquea todos los scripts en PowerShell; las tareas deben ejecutarse de forma interactiva. Política por defecto en clientes Windows
UnrestrictedEjecuta cualquier script sin restricciones. Muestra advertencia al ejecutar uno sin firmar
RemoteSignedPermite ejecutar scripts locales sin firmar, pero los paquetes descargados deben estar firmados. Para ejecutar scripts descargados sin firmar es necesario Unblock-File. Política por defecto en Windows Server
AllSignedSolo permite ejecutar paquetes y scripts firmados digitalmente por un publicador de confianza, incluidos los scripts locales
BypassSimilar a Unrestricted pero sin alertas. Usado en integraciones de PowerShell con otras aplicaciones que tienen su propio modelo de seguridad
UndefinedNo se establece explícitamente ninguna directiva. Por defecto se aplica Restricted
DefaultEstablece la política predeterminada: Restricted en clientes Windows, RemoteSigned en Windows Server

Tipos de ámbitos de la política de ejecución (Scopes):

ScopeAlcance
MachinePolicyEstablecido por GPO para todos los usuarios de la máquina
UserPolicyEstablecido por GPO para el usuario actual de la máquina
ProcessAfecta solo a la sesión actual de PowerShell
CurrentUserAfecta solo al usuario actual
LocalMachineAlcance predeterminado: afecta a todos los usuarios de la máquina

El bypass anula este hardening

Set-ExecutionPolicy Bypass -Scope Process, powershell -ExecutionPolicy Bypass o usar cmd /c powershell ... permiten saltarse cualquier policy configurada aquí. ExecutionPolicy es un freno para usuarios honestos, no un mecanismo de seguridad real. Para hardening efectivo, combínalo con AppLocker, WDAC o Constrained Language Mode.

Referencia: Get-ExecutionPolicy y Set-ExecutionPolicy

Get-ExecutionPolicy -List
Set-ExecutionPolicy AllSigned -scope LocalMachine -Force

Figura 1: Políticas de ejecución de scripts PowerShell.

Figura 1: Políticas de ejecución de scripts PowerShell.

Bypass de la política de ejecución de un solo script Link to heading

En el caso de que las políticas de ejecución estén en un modo Undefined y por lo tanto es como si estuvieran en Restricted. Si queremos ejecutar un script en esa misma sesión o contexto de ejecución podemos usar el modo Bypass.

PowerShell.exe -ExecutionPolicy Bypass -File \.MyScript.ps1

También sería lo mismo.

powershell -ep Bypass .\MyScript.ps1

Figura 2: Bypass para la ejecución de un solo script.

Figura 2: Bypass para la ejecución de un solo script.

Firmar un script PowerShell Link to heading

Referencia: Set-AuthenticodeSignature

Firmar con un certificado del almacén de certificados local Link to heading

$cert = Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert
Set-AuthenticodeSignature -FilePath MyScript.ps1 -Certificate $cert

Figura 3: Firmar con un certificado del almacén local.

Figura 3: Firmar con un certificado del almacén local.

Firmar un script usando un certificado de un archivo PFX Link to heading

$cert = Get-PfxCertificate -FilePath C:\Certs\MySign.pfx
Set-AuthenticodeSignature -FilePath MyScript.ps1 -Certificate $cert

Figura 4: Firmar usando un certificado .pfx.

Figura 4: Firmar usando un certificado .pfx.

Agregar una firma que incluya la autoridad de certificación raíz (CA) Link to heading

$cert = Get-PfxCertificate -FilePath C:\Certs\MySign.pfx
Set-AuthenticodeSignature -FilePath MyScript.ps1 -Certificate $cert -IncludeChain All -TimestampServer "http://timestamp.globalsign.com/scripts/timstamp.dll"
  • IncludeChain: Incluye todas las cadenas de confianza de la autoridad raíz.
  • TimeStampServer: Agrega una marca de tiempo a la firma. Esto evita que el script falle cuando caduque el certificado.

Figura 5: Agregar una firma que incluya la autoridad raíz.

Figura 5: Agregar una firma que incluya la autoridad raíz.

Obtener información de la firma de un script firmado Link to heading

Referencia: Get-AuthenticodeSignature

Get-AuthenticodeSignature .\MyScript.ps1 | Format-List *

Figura 6: Obtener información de la firma de un script firmado.

Figura 6: Obtener información de la firma de un script firmado.

Crear un certificado autofirmado para realizar pruebas Link to heading

Referencia: New-SelfSignedCertificate

New-SelfSignedCertificate -FriendlyName "Zona System ejemplo firma de código" -CertStoreLocation Cert:\CurrentUser\My -Subject "Zona System" -Type CodeSigningCert

Figura 7: Crear certificado autofirmado para pruebas.

Figura 7: Crear certificado autofirmado para pruebas.

Ejemplo de ejecución de script firmado Link to heading

Estableciendo la política de ejecución de scripts de PowerShell en AllSigned.

Figura 8: Ejemplo de ejecución de script firmado.

Figura 8: Ejemplo de ejecución de script firmado.

Saludos!