En este artículo se explica cómo, sin privilegios de usuario local, evitar la prohibición de ejecución de scripts en PowerShell, lo cual puede ser un obstáculo para pentesters y desarrolladores en su trabajo.
¿Qué es la Política de Ejecución de PowerShell?
La política de ejecución de PowerShell (PowerShell Execution Policy) es un parámetro que define qué tipos de scripts de PowerShell se pueden ejecutar en el sistema. Por defecto, el valor de este parámetro es “Restricted“. Cuando este modo está activado, PowerShell solo permite comandos básicos en una sesión interactiva de línea de comandos, sin permitir la carga ni la ejecución de scripts personalizados. Este ajuste protege contra la ejecución accidental o maliciosa de código dañino.
Cabe destacar que el modo “Restricted” puede limitar las capacidades de PowerShell y afectar su funcionalidad. Por ello, existen varias formas de evitar este parámetro.
¿Por qué los Administradores desean Eludir la Política de Ejecución?
La razón principal y más común es la automatización de procesos. También existen otras razones por las cuales PowerShell se ha vuelto popular entre administradores, pentesters y hackers:
- Está integrado en Windows;
- Permite la llamada a APIs de Windows;
- Facilita la ejecución de comandos sin escribir en disco;
- Ayuda a evitar la detección por antivirus;
- Permite crear conjuntos de herramientas para pentesting de código abierto.
Cómo ver la Configuración de la Política de Ejecución
Antes de utilizar todas las funciones de PowerShell, los atacantes pueden necesitar eludir la política de ejecución “Restricted”. Podemos ver la configuración actual usando el comando de PowerShell Get-ExecutionPolicy
. El valor predeterminado es “Restricted“.
También es importante señalar que la política de ejecución puede establecerse en diferentes niveles del sistema. Para ver una lista de ellos, usa el siguiente comando:
Configuración del Entorno de Prueba
En los ejemplos que se presentan, se utiliza un script llamado “ejecutame.ps1
“, que contiene el siguiente comando de PowerShell para mostrar un mensaje en la consola:
Write-Host "Mi voz es mi pasaporte, verificame"
Cuando un usuario intenta ejecutar este comando en un sistema configurado con la política de ejecución predeterminada, aparece el siguiente error:
Si tu política actual permite la ejecución de scripts y deseas establecer una restricción para probar los métodos descritos, ejecuta el comando Set-ExecutionPolicy Restricted
desde la consola de administrador de PowerShell.
Evasión de la Política de Ejecución de PowerShell
#1. Copia el script en la consola interactiva de PowerShell
Copia y pega el script de PowerShell en la consola interactiva. Ten en cuenta que estarás limitado por los privilegios de tu usuario actual. Este es el método más común para ejecutar scripts simples en la consola interactiva. Además, este método no cambia la configuración ni requiere escribir en el disco.
#2. Envía el script al flujo estándar de entrada de PowerShell
Simplemente introduce tu script en la entrada estándar de PowerShell. Este método no cambia la configuración ni requiere escribir en el disco.
echo write-host "Mi voz es mi pasaporte, verificame" | powershell -noprofile -
#3. Lee el script desde un archivo y redirígelo al flujo estándar de entrada de PowerShell
Utiliza el comando de Windows type
o el comando de PowerShell Get-Content
para leer el script desde el disco y redirigirlo a la entrada estándar de PowerShell. Este método no cambia la configuración, pero requiere escribir el script en el disco. Sin embargo, puedes leerlo desde un recurso de red compartido si deseas evitar escribir en el disco.
Ejemplo 1: Comando Get-Content
de PowerShell
Get-Content .\ejecutame.ps1 | powershell.exe -noprofile -
Ejemplo 2: Comando type
type .\ejecutame.ps1 | powershell.exe -noprofile -
#4. Descarga el script desde una URL y ejecútalo con Invoke Expression
Este método se puede usar para descargar un script de PowerShell desde Internet y ejecutarlo sin escribir en el disco. Tampoco provoca ningún cambio en la configuración.
powershell -nop -c "Invoke-Command -ScriptBlock { (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/esgeeks/Powershelles/refs/heads/main/ejecutame.ps1') }"
O,
powershell -nop -c "Invoke-Command -ScriptBlock { (New-Object Net.WebClient).DownloadString('https://bit.ly/3XGEWBm') }"
#5. Usa el modificador de funciones de PowerShell (Command Switch)
Este método es muy similar a ejecutar un script copiándolo y pegándolo, pero se puede ejecutar sin acceso a la consola interactiva. Es ideal para ejecutar scripts simples, pero los más complejos suelen generar errores de sintaxis. Este método no requiere cambiar la configuración ni escribir en el disco.
Ejemplo 1: Comando completo
powershell.exe -command "Write-Host 'Mi voz es mi pasaporte, verificame'"
Ejemplo 2: Comando acortado
Powershell -c "Write-Host 'Mi voz es mi pasaporte, verificame'"
También puedes colocar estos comandos de PowerShell en archivos por lotes y en ubicaciones de inicio automático (como la carpeta de inicio), para usar los scripts durante la elevación de privilegios.
#6. Usa el modificador EncodeCommand Switch
EncodeCommand Switch
es muy similar a Command Switch
, pero convierte todos los scripts en codificación Unicode/base64. Codificar el script de esta manera ayuda a evitar errores de sintaxis que pueden ocurrir con Command Switch
.Este método no cambia la configuración ni requiere escribir en el disco. El siguiente ejemplo fue tomado de la utilidad Posh-SecMod, que también contiene un método de compresión para reducir el tamaño de los comandos codificados si se vuelven demasiado largos.
Ejemplo 1: Comando completo
$command = "Write-Host 'Mi voz es mi pasaporte, verificame'"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
$encodedCommand
powershell.exe -encodedCommand $encodedCommand
Ejemplo 2: Comando acortado usando una cadena codificada
powershell.exe -Enc wByAGkAdAB1ACOASABvAHMAdAA....
#7. Usa el comando Invoke-Command
Normalmente, este comando se ejecuta a través de la consola interactiva de PowerShell o en combinación con el parámetro “Command”, pero también se puede usar para ejecutar scripts en sistemas remotos donde está habilitada la ejecución de scripts de PowerShell. Este método no cambia la configuración ni requiere escribir en el disco.
Get-Content .\ejecutame.ps1 | Invoke-Expression
El siguiente comando también se puede utilizar para transferir la configuración de la política de ejecución de una computadora remota a una local.
invoke-command -computername Server01 -scriptblock {get-executionpolicy} | set-executionpolicy -force
#8. Usa el comando Invoke-Expression
Este comando no requiere cambiar la configuración ni escribir en el disco.
Ejemplo 1: Comando completo utilizando Get-Content
Get-Content .\ejecutame.ps1 | Invoke-Expression
Ejemplo 2: Comando abreviado utilizando Get-Content
GC .ejecutame.ps1 | iex
#9. Usa el modificador Bypass
El modificador evitará la política de ejecución cuando ejecutes scripts desde un archivo. Microsoft afirma que al usar este modificador “no se bloquea nada y no se muestran advertencias ni mensajes”. Esta técnica no implica cambios en la configuración ni requiere escribir en el disco.
PowerShell.exe -ExecutionPolicy Bypass -File .\ejecutame.ps1
#10. Usa el modificador Unrestricted
Este modificador es similar a Bypass, pero según Microsoft, “se cargan todos los archivos de configuración y se ejecutan todos los scripts. Si ejecutas un script no firmado descargado de Internet, se te solicitará permiso antes de ejecutarlo”. Este método no cambia la configuración ni requiere escribir en el disco.
PowerShell.exe -ExecutionPolicy UnRestricted -File .\ejecutame.ps1
#11. Usa el modificador Remote-Signed
Crea tu script y luego sigue las instrucciones de Carlos Pérez para firmarlo. Después, ejecútalo con el siguiente comando:
PowerShell.exe -ExecutionPolicy Remote-signed -File .ejecutame.ps1
#12. Desactiva la ExecutionPolicy reemplazando AuthorizationManager
Esta función se puede ejecutar a través de la consola interactiva de PowerShell o en combinación con el parámetro “Command”. Al invocar la función, se reemplaza “AuthorizationManager” con null, lo que resulta en que la política de ejecución se establece como no restringida durante el resto de la sesión.
Este método no implica un cambio permanente en la configuración ni requiere escribir en el disco, pero la modificación se mantendrá activa durante toda la sesión.
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"))}
Disable-ExecutionPolicy
.\ejecutame.ps1
#13. Establece la ExecutionPolicy en el nivel de proceso
Al inicio del artículo se mencionó que la política de ejecución puede aplicarse en muchos niveles, incluido el nivel de proceso, que puedes controlar. Este método permite establecer la política de ejecución en no restringida durante la sesión. Además, el comando no cambia la configuración ni requiere escribir en el disco.
Set-ExecutionPolicy Unrestricted -scope process
#14. Establece el estado Unrestricted para el nivel CurrentUser con un comando
Este parámetro es similar al anterior, pero aplica el ajuste de forma permanente en el entorno del usuario actual, modificando una clave del registro. Además, este método no cambia la configuración ni requiere escribir en el disco.
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy UnRestricted
#15. Establece el estado Unrestricted para el nivel CurrentUser a través del registro
Aquí se muestra cómo cambiar de forma permanente la política de ejecución para el entorno del usuario actual, modificando directamente la clave del registro.
Conclusión
La política de ejecución no debería ser un obstáculo para los desarrolladores, administradores o pentesters. Microsoft nunca diseñó PowerShell para ser completamente seguro. Por ello, existen muchas formas de eludir la política de ejecución. Microsoft ha proporcionado varias herramientas integradas útiles, y la comunidad de especialistas en seguridad ha demostrado varios trucos interesantes.