Restringir PowerShell
Introducción
El capítulo anterior se ha centrado principalmente en las funciones de bloqueo de PowerShell llamadas «binarias» (es decir, autorizadas o no). Sin embargo, es posible matizar un poco más la configuración del Shell para permitir personalizaciones de uso específicas para cada organización.
A modo de recordatorio, «la ejecución de comandos a distancia» implica ejecutar código en un ordenador diferente al que estamos usando. Esto es exactamente lo que hicimos con los diferentes Reverse Shell utilizados en el capítulo Malware casero y en el capítulo PowerShell Empire. PowerShell incorpora a través de WinRM y WMI esta capacidad de trabajar de forma remota. Es posible configurar esto de manera detallada, como veremos más adelante.
El capítulo concluirá con la aplicación del modo de lenguaje restringido en el Lab para limitar PowerShell sin prohibir su uso.
Remote PowerShell
PowerShell no se limita a ser un Shell local en las máquinas Windows. Incorpora de forma nativa la capacidad de interactuar con máquinas remotas y ejecutar prácticamente cualquier comando.
Sin embargo, el acceso remoto con PowerShell se basa en numerosos protocolos de comunicación y frameworks presentes en los entornos de Microsoft.
Esta variedad de protocolos puede complicar la comprensión del remoting con PowerShell. Los protocolos disponibles para actuar de forma remota en una máquina con PowerShell son los siguientes:
-
WMI: Windows Management Instrumentation, con DCOM y RPC en el fondo.
-
WinRM: Windows Remote Management, que se basa en WSMan (Web Services-Management).
-
En las versiones de Linux (Core 7), PowerShell incluso es compatible con SSH.
Los accesos remotos en PowerShell existían desde la versión 2 del lenguaje de Microsoft. Entre 2009 y hoy, han sucedido muchas evoluciones del lenguaje y del Framework .NET, y algunos comportamientos o características pueden variar según la versión de PowerShell. Sin embargo, la mayoría de los comandos recientes se basan en el mecanismo de «sesiones», que se presentará a continuación.
1. PSSessions, WS-Management y WinRM
a. Sesiones
Las PSSessions son el mecanismo preferido por PowerShell para ejecutar comandos de forma remota. Permiten conectarse de manera puntual o persistente a uno o varios ordenadores remotos para ejecutar scripts o sesiones interactivas.
La sesión «clásica» en PowerShell, al igual que en muchos lenguajes interactivos, es el entorno en memoria en el que se cargan sus variables, módulos y códigos. Las PSSessions en la consola de PowerShell son simplemente una capa de abstracción que permite la gestión de sesiones adicionales en su sesión actual. A diferencia de una sesión clásica, estas sesiones adicionales pueden estar asociadas con un ordenador remoto.
Para gestionar la comunicación con la máquina remota, las PSSessions se basan en el servicio WinRM y el protocolo de comunicación WS-Management. WinRM es el programa que implementa la capa protocolaria.
Técnicamente, cuando ocurre una comunicación entre dos máquinas a través de sesiones PowerShell, el comando se formatea en un mensaje en formato SOAP (Simple Object Access...
PowerShell JEA: Just Enough Administration
1. Presentación
En cuanto a la conexión remota con PowerShell, tiene que ser por defecto administrador local de la máquina a la que se desea conectar para disponer de los permisos necesarios. Si bien en entornos pequeños este paradigma puede ser suficiente, en parques grandes a menudo implica el uso de cuentas altamente privilegiadas para la administración remota.
Las lecciones aprendidas en el capítulo PowerShell Empire nos enseñan que el compromiso de este tipo de cuenta es muy perjudicial, ya que permite a un atacante moverse lateralmente en el mejor de los casos, o tomar el control del dominio en el peor.
Como se vio en la sección anterior, la implementación técnica de la gestión de privilegios para el acceso remoto con PowerShell es compleja, ya que se basa en varios mecanismos (WSman, WinRM, PSSessions, WMI y RPC, o incluso DCOM) que pueden desempeñar un papel. Además, estos mecanismos no permiten una gestión diferenciada de los derechos de cada usuario. No sería posible otorgarle a Federico los privilegios sobre la administración del DNS del dominio y a Arnaldo los privilegios sobre los registros de diferentes máquinas.
Introducido desde PowerShell 5, JEA es el mecanismo que aborda estos problemas. Al asociar cuentas virtuales temporalmente privilegiadas con derechos específicos, los usuarios autorizados en JEA pueden realizar acciones autorizadas con cuentas estándar, incluso si estas acciones en teoría requieren privilegios de administración. JEA funciona a través de un PowerShell en sandbox configurado en no language mode (que se verá en la siguiente sección) y aborda el tema de la seguridad de las acciones de administración remota con PowerShell.
2. Estrategia de implementación
Antes de implementar una estrategia de JEA, es imperativo mapear el uso de PowerShell para la administración en su SI. De hecho, más allá de la configuración técnica de JEA, el desafío es encontrar el equilibrio entre lo que los administradores necesitan para realizar su trabajo y no otorgar demasiado acceso para evitar facilitar el trabajo de un atacante (lo que volvería a la situación inicial de acceso WinRM sin JEA).
Este trabajo minucioso depende de su organización, su tamaño...
Constrained Language Mode y AppLocker
1. Language Mode
Antes de hablar sobre el modo de lenguaje restringido, es necesario mencionar los diferentes modos de lenguaje que PowerShell ofrece. En la práctica, según el modo seleccionado, ciertas funciones, cmdlet, palabras clave o técnicas estarán permitidas o no. Hay cuatro modos de lenguaje en PowerShell:
-
FullLanguage: este es el modo predeterminado, en el que no se aplican restricciones.
-
RestrictedLanguage: en este modo, la mayoría de los cmdlets están permitidos, pero muchas variables no son accesibles, los bloques de scripts y el acceso a las propiedades de los objetos están bloqueados y solo tres operadores de comparación son accesibles (-eq, -gt, -lt).
-
NoLanguage: este es un modo específico que solo se puede usar con la API de PowerShell. En este modo, solo las funciones de la API AddCommand y AddScript están autorizadas, como se muestra en el siguiente ejemplo.
$session = [powershell]::Create()
$session.RunSpace.SessionStateProxy.LanguageMode = 'NoLanguage'
$session.AddScript('Get-Date').Invoke()
-
ConstrainedLanguage: en el modo restringido, al igual que en el modo restricted, todos los cmdlets y elementos del lenguaje están autorizados. Sin embargo, los tipos accesibles están limitados, se bloquea la conversión de tipos y se imponen muchas restricciones en el funcionamiento de PowerShell. Solo las funciones explícitamente exportadas desde scripts o módulos son accesibles. Los objetos COM y las clases están bloqueados, y la utilización de puntos de interrupción y de los Jobs/ScheduledJobs está igualmente prohibida. Este modo solo existe a partir de PowerShell V3.
El modo de lenguaje aplicado a la sesión actual se puede verificar de la siguiente manera:
> $ExecutionContext.SessionState.LanguageMode
FullLanguage
Al igual que la execution policy, el modo de lenguaje puede ser modificado por el usuario:
> [System.Math]::Exp(2)
7,38905609893065
> $ExecutionContext.SessionState.LanguageMode =
"ConstrainedLanguage"
> [System.Math]::Exp(2)
Imposible llamar al método. La llamada a métodos sólo se admite en
los tipos principales de este modo de lenguaje.
Sin embargo, al igual que con la execution policy, el modo de lenguaje...
Conclusión
En este capítulo, hemos visto cómo configurar sesiones remotas en PowerShell con WinRM o WMI. Luego, vimos cómo asegurarlas y restringirlas utilizando los mecanismos del sistema de WinRM y DCOM y las reglas de firewall asociadas.
Continuamos con la solución integrada JEA. Esto permite asignar permisos con un nivel de granularidad hasta el detalle de cada cmdlet. Sin embargo, JEA requiere un trabajo preparatorio bastante considerable antes de su implementación.
Finalmente, el modo de lenguaje restringido ilustró cómo es posible restringir eficazmente y de manera predeterminada el acceso a PowerShell para los usuarios del SI. Aunque no sea invulnerable, el modo de lenguaje restringido es una barrera muy difícil de eludir para un atacante. Esta barrera debería implementarse de manera predeterminada para todos los usuarios del entorno de sistemas que no necesiten utilizar PowerShell (por supuesto, es necesario permitir un acceso normal a la consola de PowerShell para los administradores informáticos).
A lo largo de los años, PowerShell ha adquirido muchas funciones. Los dos últimos capítulos han abordado las siguientes:
-
El bloqueo puro y simple de PowerShell mediante GPO.
-
La aplicación de la execution policy.
-
La firma de código de los scripts PS1.
-
La protección antivirus de las sesiones con AMSI.
-
La implementación y seguridad de accesos...