Windows PowerShellProtezione della shell

Don Jones

Quando il team di Windows PowerShell si è ritrovato intorno a un tavolo per iniziare a creare una nuova shell e nell'aria vagheggiava la parola "script", per tutta Redmond si udivano sospiri di costernazione. Dopotutto, i precedenti sforzi di Microsoft con lo script amministrativo (mi riferisco a VBSCRIPT) non erano stati esattamente privi di problemi. Un modello

di esecuzione eccessivamente permissivo, combinato con la propensione della maggior parte degli utenti ad accedere come amministratori, ha aperto la strada al disastro.

"Sicuramente" chi ha preso parte al primo incontro su Windows PowerShell™ deve aver pensato "non ricadremo nello stesso errore!" E così è stato. Microsoft ha migliorato enormemente la sua reputazione in termini di protezione, fondamentalmente perché nel ciclo di sviluppo di un prodotto l'attenzione è stata focalizzata subito sulla protezione. Questa filosofia è molto evidente in Windows PowerShell.

Perché i miei script non verranno eseguiti?

Installare Windows PowerShell su un computer nuovo e fare doppio clic su un file .ps1: viene visualizzato il Blocco note, non Windows PowerShell. Ciò avviene perché l'estensione del nome del file ps1, ossia quella utilizzata per gli script di Windows PowerShell, non ha alcuna correlazione con la shell stessa. In altre parole, non è possibile fare doppio clic su uno script per eseguirlo. L'unico modo per eseguire uno script è aprire Windows PowerShell, immettere il tipo di script e premere Invio.

A dire il vero, non è sufficiente immettere semplicemente il nome dello script. Come si può vedere nella Figura 1, il file Demo1.ps1 esiste nella cartella corrente, eppure digitando demo1 e premendo Invio viene visualizzato un messaggio di errore: "Il termine "demo1" non è riconosciuto come un cmdlet, una funzione, un programma eseguibile o un file script". Perché? Dopotutto, il file si trova proprio lì.

Figura 1 Per evitare il dirottamento del comando, Windows PowerShell richiede allo script un percorso

Figura 1** Per evitare il dirottamento del comando, Windows PowerShell richiede allo script un percorso **(Fare clic sull'immagine per ingrandirla)

Questo è un altro aspetto del modello di protezione di Windows PowerShell. Spesso, gli utenti malintenzionati usano in altre shell il trucchetto di creare uno script con lo stesso nome del file come un comando integrato. Così, ad esempio, se si desidera che un utente esegua lo script, si potrebbe denominare lo script Dir.ps1 e inserirlo in una cartella. Se l'utente digita Dir e preme Invio, è possibile che venga eseguito lo script e non il comando Dir previsto dall'utente. Questa tecnica è definita dirottamento del comando. In Windows PowerShell, è necessario fornire sempre un percorso a uno script di questo tipo, proteggendo piuttosto bene Windows PowerShell dal dirottamento del comando.

L'esecuzione di demo1 non funziona, perché non è stato specificato alcun percorso, mentre ./demo1 funziona. Questo è il motivo per cui adesso è stato specificato un percorso, ossia l'attuale cartella. È molto meno probabile che quella riga di comando venga confusa con un comando integrato poiché non è necessario immettere alcun tipo di percorso se si fa riferimento a un comando integrato. Pertanto, la richiesta di un percorso consente a Windows PowerShell di evitare il dirottamento del comando e l'eventuale confusione su cosa potrebbe accadere se si preme Invio.

Un criterio per l'esecuzione degli script

A questo punto, si ha una copia di Windows PowerShell installata di recente, si utilizza la sintassi appropriata e si tenta di eseguire uno script. Con grande sorpresa, si viene accolti da un altro messaggio di errore che indica che Windows PowerShell non può eseguire gli script. Cosa??? Benvenuti in Criteri di esecuzione della shell.

Tramite l'esecuzione di Get-ExecutionPolicy nella shell, è possibile scoprire cosa si intende per Criteri di esecuzione. Per impostazione predefinita, è impostato su Restricted, il che indica semplicemente che gli script non verranno eseguiti mai, per nessuno. Per impostazione predefinita, Windows PowerShell può essere utilizzato solo in modalità interattiva e non per eseguire gli script. È possibile utilizzare il cmdlet Set-ExecutionPolicy per scegliere una delle quattro possibili impostazioni di Criteri di esecuzione:

  • Restricted, l'impostazione predefinita, non consente l'esecuzione di nessuno script.
  • AllSigned esegue soltanto script attendibili (ulteriori informazioni su questo argomento verranno fornite più avanti).
  • RemoteSigned esegue gli script locali senza la necessità che siano attendibili. È necessario, tuttavia, che gli script scaricati da Internet siano attendibili prima di essere eseguiti.
  • Unrestricted consente l'esecuzione di tutti gli script, persino di quelli non attendibili.

Francamente, AllSigned è l'impostazione minima che dovrebbe essere eseguita in un computer di produzione. RemoteSigned è utile negli ambienti di sviluppo e di test, ma non è necessario per l'utente comune. Invece non c'è alcun bisogno di Unrestricted. Non dovrebbe importare se in alcune versioni future di Windows PowerShell venisse omessa questa impostazione eccessivamente permissiva.

È una questione di attendibilità

Il computer viene preconfigurato per considerare attendibili determinate Autorità di certificazione (CA) principali, ossia server che emettono certificati digitali. Nella Figura 2 viene illustrata l'applicazione del pannello di controllo Opzioni Internet, in cui vengono elencate le principali CA attendibili. In Windows Vista® questo elenco è piuttosto breve e contiene soltanto alcune delle principali CA commerciali. Al contrario, l'elenco predefinito in Windows® XP è ampio e contiene molte CA principali mai incontrate prima. Se una CA principale si trova in questo elenco, significa fondamentalmente che la società che utilizza la CA principale è considerata attendibile ed è in grado di verificare l'identità di qualcuno prima di emettere un certificato digitale.

Quando si ottiene un certificato digitale Class III, l'autorità di certificazione (che potrebbe essere una CA commerciale o una CA privata presente all'interno dell'organizzazione) deve verificarne l'identità. Questo certificato digitale è simile a un passaporto o una carta d'identità elettronica. Prima di fornire un ID, ad esempio Don Jones, la CA effettua alcune operazioni per verificare che l'utente in questione sia realmente Don Jones. Quando si utilizza un certificato per firmare digitalmente uno script di Windows PowerShell, operazione eseguibile tramite il cmdlet Set-AuthenticodeSignature, la propria firma viene apposta allo script. Di certo, se si è in grado di ottenere un certificato falso contenente il nome di qualcun altro, è possibile apporre quella firma allo script. Questo è il motivo per cui è così importante che nell'elenco riportato nella Figura 2, siano presenti solo autorità di certificazione attendibili.

Figura 2 Principali autorità di certificazione attendibili in Windows Vista

Figura 2** Principali autorità di certificazione attendibili in Windows Vista **(Fare clic sull'immagine per ingrandirla)

Quando Windows PowerShell verifica se uno script è attendibile (operazione eseguita con le impostazioni dei Criteri di esecuzione AllSigned e RemoteSigned) pone tre domande:

  • Questo script è firmato? Se non lo fosse, lo script non è attendibile.
  • La firma è intatta? In altre parole, lo script è cambiato da quando è stato firmato? Se la firma non è intatta, lo script non è attendibile.
  • La firma è stata creata utilizzando un certificato digitale emesso da una autorità di certificazione principale attendibile? Se non lo fosse, lo script non è attendibile.

CMDLET del mese: Set-AuthenticodeSignature

Set-AuthenticodeSignature è la chiave per firmare digitalmente gli script di Windows PowerShell che consente l'uso dei criteri di esecuzione più sicuri della shell, AllSigned. Per utilizzare questo cmdlet, si parte con un altro, Get-ChildItem, che recupera un certificato di firma del codice installato:

$cert = Get-ChildItem –Path cert:\CurrentUser\my –codeSigningCert

È necessario sostituire quel percorso di file con uno che indirizzi a un certificato installato poiché ciascun certificato installato viene reso accessibile tramite l'unità cert:. Una volta caricato il certificato, per firmare uno script è necessario procedere come segue:

Set-AuthenticodeSignature MyScript.ps1

–cert $cert

Naturalmente fornire il percorso completo al file di script ps1. La shell aggiungerà un blocco di firma al file.

In che modo l'attendibilità migliora la protezione? Di certo, un utente malintenzionato potrebbe scrivere potenzialmente uno script dannoso, firmarlo e convincere qualcuno nel suo ambiente a eseguirlo. Poiché lo script è stato firmato, verrà eseguito. Ma poiché è stato firmato, è possibile utilizzare la firma per trovare l'identità dell'autore e prendere contromisure appropriate (ad esempio chiamare le autorità competenti). Una persona dovrebbe essere estremamente stupida, tuttavia, per creare uno script dannoso e inserirvi il proprio vero nome.

Certo, se un utente malintenzionato fosse in grado di ottenere un certificato con l'identità di qualcun altro, ossia da una CA che non è stata sottoposta a un valido processo di verifica dell'identità, non sarebbe possibile utilizzare la firma per identificare il vero colpevole. Questo è il motivo per cui le principali autorità di certificazione devono disporre di un processo di verifica dell'identità appropriato.

Se si utilizza l'impostazione AllSigned di Criteri di esecuzione, è necessario firmare digitalmente anche ogni script prodotto prima che venga eseguito. Il cmdlet Set-AuthenticodeSignature è abbastanza facile da utilizzare, ma potrebbe creare non pochi problemi. Ecco dove il software di terzi potrebbe risultare utile. Si consiglia di selezionare un editor di script o un ambiente di sviluppo visivo che firmerà automaticamente gli script utilizzando il certificato specificato. In questo modo, l'uso delle firme è trasparente e non richiede alcuno sforzo aggiuntivo. Per suggerimenti su editor e ambienti di sviluppo che supportano questa operazione, visitare alcuni forum in linea sugli script (ad esempio il sito SscriptingAnswers.com) e inviare un messaggio in cui si chiede cosa utilizzano gli altri sostenitori di Windows PowerShell.

Una volta ottenuto un certificato, è possibile anche eseguire la singola riga di codice indicata di seguito per firmare tutti gli script in una posizione particolare:

Get-Childitem *.ps1 | %{Set-AuthenticodeSignature $_.fullname $cert}

Protetto centralmente

I Criteri di esecuzione di Windows PowerShell possono, ovviamente, essere configurati singolarmente su ciascun computer. Ma non è un'ottima soluzione per gli ambienti aziendali. È, invece, possibile utilizzare Criteri di gruppo. È possibile scaricare i modelli amministrativi di Windows PowerShell dal sito go.microsoft.com/fwlink/?LinkId=93675. Inserire semplicemente il file in un oggetto Criteri di gruppo (GPO, Group Policy Object) che interessa l'intero dominio e impostarlo su Restricted. In questo modo, a prescindere da dove venga installato Windows PowerShell, è possibile accertarsi che gli script non verranno eseguiti. In seguito, è possibile applicare un'impostazione più permissiva (AllSigned) solo sui computer in cui sono in esecuzione gli script (come la propria workstation).

Credenziali alternative

A differenza dei precedenti linguaggi di scripting amministrativi per Windows, Windows PowerShell è in grado di utilizzare qualsiasi credenziale alternativa in maniera sicura. Ad esempio, il cmdlet Get-WMIObject dispone di un parametro, -credential, che consente di specificare una credenziale alternativa per le connessioni WMI remote. Il parametro accetterà un nome utente ma non una password, impedendo così di specificare a livello di codice password sensibili in un chiaro script di testo. Al contrario, quando si fornisce il nome utente, Windows PowerShell richiede la password tramite una finestra di dialogo. Se si progetta di utilizzare nuovamente una credenziale alternativa, è possibile memorizzare le informazioni di autenticazione utilizzando il cmdlet Get-Credential:

$cred = Get-Credential DOMAIN\USER

verrà richiesta immediatamente la password e la credenziale finale verrà memorizzata nella variabile $cred. È possibile poi passare tale variabile al parametro –credential più spesso del necessario. È persino possibile utilizzare i cmdlet ConvertTo-SecureString e ConvertFrom-SecureString per convertire la credenziale in una stringa crittografata o convertire nuovamente una stringa precedentemente crittografata in una credenziale.

Il problema è che la chiave di crittografia finisce con l'essere memorizzata in uno script di testo normale, il che compromette completamente la protezione. Dunque, invece di procedere in questo modo è possibile aggiungere una chiamata Get-Credential al profilo di Windows PowerShell. Successivamente, quando si esegue Windows PowerShell, viene richiesto immediatamente di inserire un nome utente e una password, entrambi memorizzati in una variabile denominata $cred. In questo modo, si dispone sempre di una variabile $cred nella shell che rappresenta un account amministratore di dominio. Poiché la credenziale viene ricreata ogni volta che si apre la shell, non è necessario memorizzarla.

Protetto per impostazione predefinita

Per impostazione predefinita, Windows PowerShell viene installato e configurato con le impostazioni più sicure sviluppate per una shell amministrativa che supporta lo scripting. A meno che tali impostazioni non vengano modificate, Windows PowerShell rimarrà protetto. In altre parole, tutto ciò che riduce la protezione in Windows PowerShell è il risultato delle proprie decisioni e azioni. Pertanto, prima di modificare qualsiasi impostazione predefinita, mediante la riconfigurazione delle associazioni di estensione del file, la modifica dei Criteri di esecuzione e così via, accertarsi di aver compreso quali possono essere le conseguenze delle proprie azioni e assumersi la responsabilità delle modifiche apportate.

Don Jones è il guru degli script di SAPIEN Technologies e istruttore per ScriptingTraining.com. È possibile contattare Don tramite il suo sito Web, ScriptingAnswers com.

© 2008 Microsoft Corporation e CMP Media, LLC. Tutti i diritti riservati. È vietata la riproduzione completa o parziale senza autorizzazione.