Gestione delle policy di sicurezza in PowerShell

PowerShell è sempre più uno strumento di governo e gestione dei sistemi che quotidianamente devono essere amministrati in un’infrastruttura IT.

A prescindere dalla dimensione e dal numero di postazioni gestite in ci si può trovare ad eseguire script in Powershell, le impostazioni di default non ne permettono l’esecuzione in modo automatico ed il comando che sovente viene eseguito è set-executionpolicy unrestricted, che permette da un lato l’esecuzione di uno script, ma dall’altro espone il sistema ad attacchi di Malware che sfruttano proprio PowerShell per infiltrarsi.

Proviamo a capire meglio quali sono i contesti di sicurezza in cui opera Powershell e quindi a capire quando e se è necessario “abbassare” i livelli di protezione per l’esecuzione degli script che devono essere eseguiti.

1) Execution Policy

Le execution policy determinano le condizioni per le quali l’ambiente PowerShell carica ed esegue uno script in modo automatico. Normalmente è richiesto che venga aperta una sessione PS e solo successivamente venga eseguito manualmente lo script.

Le Execution Policy possono, e sono, applicate a 5 contesti ben definiti che vengono identificati con il nome di Scope In questo modo è possibile essere ancora più precisi nella definizione del contesto in cui un particolare script deve operare; ad esempio è possibile definire che possano essere eseguiti esclusivamente script firmati digitalmente nel contesto Macchina mentre nel contesto Utente non sia ammessa l’esecuzione automatica di alcuno script.

Le Execution Policy possono essere:

  • Restricted
  • Unrestricted
  • Allsigned
  • RemoteSigned
  • Bypass
  • Undefined

ed ognuna di queste può essere applicata in un particolare Scope, che a sua volta può essere:

  • CurrentUser
  • LocalMachine
  • Process
  • MachinePolicy
  • UserPolicy

Le impostazioni del contesto Utente e Macchina (CurrentUser, LocalMachine) trovano la loro collocazione all’interno del registry, rispettivamente nei rami HKEY_CURRENT_USER e HKEY_LOCAL_MACHINE, mentre per il contesto Process, ossia la sessione di esecuzione, l’impostazione risiede in memoria e viene cancellata quando termina la sessione.

I contesti MachinePolicy e UserPolicy sono impostati ed impostabili esclusivamente tramite GPO.

1.1) Visualizzazione delle impostazioni correnti

Tramite    PowerShell è possibile visualizzare le impostazioni di sicurezza dell’ambiente in esecuzione. La cmdlet da utilizzare è Get-ExecutionPolicy e se eseguita senza opzioni riporta le impostazioni correnti.

Figura 1: Rilevazione delle impostazioni correnti

Se vogliamo invece rilevare quelle che sono le impostazioni correnti per tutti gli Scope dovremo digitare Get-ExecutionPolicy -list oppure per un singolo Scope Get-ExecutionPolicy -Scope <NomeScope>

Figura 2: Rilevazione delle impostazioni per tutti gli scope

Osservando il risultato della cmdlet possiamo notare che è sostanzialmente diverso pur rilevando le impostazioni correnti. Questo è dovuto al fatto che in figura 1 è riportata la Execution Policy effettivamente attiva nel contesto utente che ha eseguito il comando, ossia Resticted, mentre in figura 2 è riportata l’impostazione della Execution Policy per tutti gli scope, ed in questo caso non vi è alcuna impostazione.

Nel caso di impostazione di default (Undefined ), PowerShell utilizza la policy di esecuzione Restricted a garanzia di un maggior grado di protezione, come si evince in figura 1 .

2) Modalità operative della Execution Policy

Come già accennato, ogni ExecutionPolicy permette di definire con precisione la tipologia di script che può essere eseguita e la modalità di esecuzione. Tutte le modalità sono attivabili con la cmdlet Set-ExecutionPolicy <Policy> -Scope <Scope>

2.1) Restricted

È la modalità di default e di fatto non permette l’esecuzione di nulla se non tramite l’esplicita azione dell’utente che, selezionato lo script deve effettuare la scelta “Esegui con Powershell”. Nel caso in cui si tenti l’esecuzione dello script il messaggio sarà il seguente:

Figura 3: Blocco di esecuzione Resticted

Di default non è permessa l’esecuzione di file di configurazione e formattazione (.ps1xml), Module script (.psm1), e Script (.ps1) mentre è permessa l’esecuzione in shell di singoli comandi.

2.2) Unrestricted

È l’impostazione esattamente contraria alla precedente, ossia qualunque esecuzione è permessa di qualunque tipo di script, l’impostazione Unrestricted è attivabile con il comando Set-ExecutionPolicy -unrestricted -Scope <Scope>

Figura 4: Set-executionpolicy Unrestricted

È sconsigliata l’appplicazione al contesto LocalMachine in quanto automaticamente sarebbe ereditata da tutti gli utenti che accedono al sistema come si può vedere nelle figg. 5/6

Set-ExecutionPolicy Unrestricted -Scope LocalMachine

Figura 5: Assegnazione al contesto di macchina

Get-executionPolicy -List

Figura 6: Impostazione ereditata dall’utente

Questa impostazione è sconsigliata come impostazione definitiva e potrebbe essere un buon compromesso l’applicazione nello Scope Process in modo che al termine della sessione di lavoro il contesto utente sul sistema abbia sempre il grado di protezione dei default.

2.3) AllSigned

Con questa impostazione è permessa l’esecuzione di Script e Configuration file a condizione che siano firmati da un certificato emesso da una CA attendibile. Ad esempio una CA di tipo enterprise con un Trust Level a livello di dominio o foresta potrebbe essere utilizzata per la firma di Script Powershell da utilizzare con questa impostazione di sicurezza. Viene proposto all’utente un Warning in caso di esecuzione di uno script firmato con un certificato di una CA non riconosciuta.

Figura 7: Ciclo di esecuzione e warning per file .ps1 firmato con certificato non attendibile

Mentre non viene eseguito nulla in caso di Script non firmato da certificato valido.

Figura 8: Blocco esecuzione per file non valido

Un residuo rischio per la sicurezza è possibile in quanto potrebbero essere eseguiti script firmati ma contenenti codice malevolo.

2.4) RemoteSigned

Questa impostazione è una via di mezzo tra l’esecuzione libera e quella più rigida di AllSigned. Il comportamento segue le condizioni ai punti qui sotto

  • è permessa l’esecuzione di Script locali, dove per locali si intende non scaricati dal Web,
  • è permessa l’esecuzione di script scaricati dal Web e non firmati digitalmente a patto che sia stato rimosso il blocco tramite il commandlet Ublock-File
  • è l’impostazione predefinita per i sistemi Server

2.5) Bypass

Con questa impostazione nulla viene bloccato e dal punto di vista della sicurezza è l’impostazione più critica. È la policy di esecuzione che viene utilizzata quando Powershell è un componente di un ambiente più esteso e che dispone di un proprio modello di sicurezza.

2.6) Undefined

E’ l’impostazione che non prevede impostazioni, ma che di fatto come già detto in precedenza corrisponde a Restricted

3) Execution Policy Scope

Come accennato prima lo Scope di applicazione delle Policy di esecuzione può essere definito come il confine entro il quale vengono applicate le Execution Policy. È possibile utilizzare 3 scope differenti, Process, CurrentUser, LocalMachine.

Tuttavia, il command-let Get-ExecutionPolicy riporta altri due Scope MachinePolicy e UserPolicy che non sono direttamente modificabili ma vengono utilizzati quando l’impostazione delle Policy di Esecuzione avviene tramite GPO, come analizzeremo più avanti.

3.1) Process

Quanto impostato a questo livello è valido solamente per la sessione corrente del processo PowerShell. Contrariamente agli altri due Scope la sua impostazione non risiede nel registry, ma in una variabile di sistema che non può essere modificata all’interno della sessione, la sua eventuale modifica può avvenire esclusivamente tramite la cmdlet SetExecutionPolicy.

$env:PSExecutionPolicyPreference

Figura 9: Rilevazione impostazione dell’ambiente

Una nuova sessione PS avrà quindi le impostazioni di Default

3.2) CurrentUser

L’impostazione definita in questo Scope sarà valida per l’utente corrente e non per altri e la sua configurazione è definita in nella chiave di registro HKEY_CURRENT_USER\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

All’interno è definita una chiave con nome ExecutionPolicy che contiene l’effettiva Policy di Esecuzione.

Figura 10: Rilevazione impostazione da PS e tramite registry

Si noti che la chiave è presente solo se sono definite delle impostazioni differenti da Undefined, nel caso non sia dichiarato nulla la chiave non è presente, così come pure il ramo “Powershell

3.3) LocalMachine

Questa impostazione è analoga alla precedente dal punto di vista della sua definizione, anche in questo caso è definita la stessa chiave di registro nel ramo LOCAL_MACHINE in: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

Figura 11: Impostazione a livello LocalMachine

4) Ordine di applicazione delle ExecutionPolicy

Nel caso vengano impostate regole differenti a livello utente, in contrasto con quelle definite a livello macchina, saranno applicate le prime.

Figura 12: Ordine di applicazione

Con questa particolare impostazione nel contesto utente l’effettivo permesso di esecuzione corrisponde a Bypass la reimpostazione a valori di default delle policy di esecuzione può essere effettuata con il comando

Set-ExecutionPolicy Unrestricted -Scope <Scope>

Se non viene specificato uno scope il default è applicato a LocalMachine

4.1) Avvio di una singola sessione con ExecutionPolicy particolari

È possibile avviare una singola sessione o un singolo script PowerShell con Policy di sicurezza differenti rispetto a quella che è l’impostazione predefinita.

Questa possibilità è utile nel caso si debba verificare uno script prima che venga introdotto in produzione, ma anche in ambienti di tipo WorkGroup in cui non sono presenti GPO, che come vedremo più avanti permettono l’impostazione centralizzata della sicurezza di esecuzione di PowerShell.

Per avviare uno script in modo che venga eseguito con una ExecutionPolicy RemoteSigned dovremo avviare lo script con il comando

powershell -ExecutionPolicy RemoteSigned -Command c:\samplescript\samplescript.ps1

Al Paragrafo successivo vengono analizzate le GPO che permettono di gestire centralmente PowerShell, nel caso in cui siano presenti queste impostazioni, anche la singola esecuzione del comando visto sopra non sarà permessa se in disaccordo con quanto definito a livello di dominio

Figura 13: Applicazione impostazione di dominio

5) Gestione delle Policy di Esecuzione tramite GPO

La descrizione delle impostazioni di sicurezza dell’ambiente viste finora rimane confinata all’interno di un singolo sistema, non sono disponibili in questo contesto impostazioni che possono essere distribuite su più postazioni.

All’interno di un Dominio Active Directory è possibile configurare GPO che possono essere applicate al contesto Utente o al contesto Macchina, queste impostazioni permettono di definire le Policy di Esecuzione dell’ambiente PowerShell in modo centralizzato e con gli stessi risultati che si otterrebbero tramite le cmdlet visti sopra.

Nel paragrafo 3 abbiamo analizzato i vari scope di applicazione locale, vedremo adesso, tramite GPO, le impostazioni degli scope MachinePolicy e UserPolicy, che sono utilizzati in relazione alla corrispondente GPO attivata in AD.

Figura 14: Impostazione di GPO per macchina

Quando vengono attivate queste GPO è bene sapere che alcuni comportamenti vengono modificati nel modo seguente

  • Quando viene applicata una Execution Policy tramite GPO nello scope MachinePolicy non è più possibile modificare il comportamento dello Scope CurrentUser
  • Quando viene applicata una Execution Policy tramite GPO nello scope MachinePolicy non è più possibile modificare il comportamento dello Scope Process
  • Quando viene applicata una Execution Policy tramite GPO nelle scope MachinePolicy le impostazioni eventualmente presenti localmente vengono ignorate

Figura 15: GPO assegnata MachinePolicy

In questo esempio è riportato il warning che informa della presenza di impostazioni “esterne” che sono applicate a prescindere da quello locali

  • Quando vengono applicate due policy di esecuzione, una all’utente ed una alla macchina tramite GPO, l’impostazione contenuta nella Policy di macchina determina il comportamento dell’ambiente

5.1) Creazione delle Group Policy Object (GPO)

All’interno dei componenti di Windows, sia di macchine che di utente in WindowsComponents\WindowsPowershell sono disponibili le impostazioni relative all’ambiente PS, per definire le policy di esecuzione è necessario attivare “Turn on Script Execution” e sceglierne l’impostazione

Figura 16: Impostazione della sicurezza relativa alla Execution Policy di PowerShell

All’interno sono presenti le scelte

  • Allow only signed scripts
  • Allow local scripts and remote signed scripts
  • Allow all scripts

Ognuno di questi attiva i comportamenti visti sopra al punto 2 con le corrispondenze seguenti

  • Allow only signed scripts à AllSigned
  • Allow local scripts and remote signed scripts à RemoteSigned
  • Allow all scripts à Bypass

Figura 17: Definizione della GPO Machine

Conclusioni

L’ambiente Powershell è ormai il principale linguaggio di scripting e di gestione degli ambienti Windows, tuttavia le considerazioni in merito alla sua sicurezza rischiano di essere marginali ed in questo modo il rischio di esposizione ad exploit e malware che lo sfruttano è reale concreto.

Il malware Poshspy backdoor, ad esempio, sfrutta l’ambiente Powershell per la sua diffusione.

Riferimenti

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-6