Windows PowerShellFirmare qui, prego

Don Jones

Nell'articolo di gennaio 2008 di Windows PowerShell, ho sottolineato l'importanza della firma digitale negli script di Windows PowerShell. Ho anche descritto scenari in cui un qualsiasi criterio di esecuzione diverso da AllSigned può creare vulnerabilità della sicurezza significative nell'ambiente.

Un argomento che non ho affrontato nel dettaglio è come firmare gli script nella pratica. L'articolo di gennaio è all'indirizzo technetmagazine.com/issues/2008/01/PowerShell. Non è difficile indovinare quale sarà l'argomento di questo mese.

Più di una semplice firma

La parola firma è il termine tecnicamente corretto per indicare l'argomento dell'articolo, ma non è una descrizione davvero soddisfacente di ciò che succede quando si utilizza una firma. Apporre una firma a uno script non significa che lo si approva o autorizza, come accade con un contratto o con una ricevuta della carta di credito. Nel mondo della sicurezza digitale, l'apposizione della firma equivale ad associare la propria identità a qualcosa e a garantire che lo stato o la condizione di tale "qualcosa" non è stato in alcun modo modificato. Tutto si basa sulla crittografia e la crittografia (almeno in questo caso) inizia da una coppia di chiavi di crittografia.

Le chiavi vengono definite come chiavi asimmetriche, perché sono una diversa dall'altra. La coppia è costituita da una chiave privata, accessibile solo a chi la emette, e da una chiave pubblica, che è accessibile a tutti. Questa è una semplificazione, ma fondamentalmente tutto ciò che è crittografato con la chiave privata può essere decrittato esclusivamente con la chiave pubblica corrispondente.

Il processo è più o meno tutto qui e le semplificazioni hanno l'ovvio scopo di far procedere rapidamente la discussione. Si immagini di disporre di uno script di Windows PowerShell® da firmare e di un certificato che contiene una chiave privata da utilizzare per firmare lo script. In Windows PowerShell esiste un cmdlet, che verrà illustrato a breve, che consente di unire script e certificato ed eseguire la firma effettiva. Windows PowerShell in questi casi crittografa lo script utilizzando la chiave privata. La copia crittografata viene visualizzata come del testo senza senso che viene aggiunto alla fine dello script, come una serie di commenti (vedere la Figura 1). Anche l'identità dell'autore dello script viene codificata, ma non crittografata, nei commenti e può essere letta senza ricorrere alla decrittazione.

Figura 1 Blocco della firma memorizzato alla fine dello script

Figura 1** Blocco della firma memorizzato alla fine dello script **(Fare clic sull'immagine per ingrandirla)

In seguito, quando analizza la firma, Windows PowerShell decifra l'identità e la utilizza per ottenere la chiave pubblica. Poiché solo questa specifica chiave pubblica consente di decrittare il resto della firma, per Windows PowerShell è evidente che, se è possibile decrittare la firma, significa che il firmatario corrisponde. Se il firmatario fosse un altro, la chiave pubblica non consentirebbe di decrittare la firma. Dopo aver decrittato la firma, Windows PowerShell confronta lo script alla copia crittografata nella firma. Se corrispondono, la firma viene considerata intatta. Se i due script differiscono, la firma viene considerata violata e non valida.

È così che le firme proteggono gli script di testo dalla modifica non autorizzata. Mentre lo script può essere facilmente modificato, la firma non può essere falsificata in modo da corrispondere allo script modificato senza utilizzare la chiave privata dell'autore, che ne è l'unico possessore.

Anche questa è indubbiamente una semplificazione del processo tecnico che sottende la firma. Nella realtà, le firme possono contenere ulteriori informazioni, come una copia della chiave pubblica, l'autorità di certificazione (CA) che ha emesso le chiavi e così via. Ma la descrizione fatta finora aiuta di certo a delineare le parti importanti del processo e a evidenziare il fatto che una firma protegge lo script dalla modifica non autorizzata.

Un fattore di sicurezza critico è la protezione assoluta della chiave privata, che non deve finire in altre mani. Quando si installa la chiave in Windows, è necessario proteggerla immediatamente con una password, in modo che un processo dannoso non possa utilizzarla contro la volontà del proprietario della chiave. Le smart card garantiscono condizioni di sicurezza ancora migliori, poiché contengono la chiave privata. Con una smart card, la chiave privata non lascia mai la scheda. Invece, i dati da crittografare vengono trasmessi alla smart card mediante l'hardware del lettore, mentre la crittografia e il successivo invio del risultato vengono eseguiti dai circuiti della smart card.

Come ottenere un certificato

Cmdlet del mese: Export-CSV

I frequentatori dei forum di PowerShellCommunity.org spesso chiedono se Windows PowerShell consente di eseguire esportazioni in Microsoft Excel®. Certo che lo consente! Basta usare il cmdlet Export-CSV, dal momento che Excel può aprire, modificare e salvare in modalità nativa i file CSV. Per esportare un elenco di servizi, ad esempio, è sufficiente eseguire Get-Service | Export-CSV MyServices.csv. Infatti, si può aggiungere Export-CSV alla fine di qualsiasi pipeline e tutti gli oggetti della pipeline vengono aggiunti al file CSV specificato. Per impostazione predefinita, Export-CSV aggiunge una riga di intestazione all'inizio del file, che viene quindi utilizzata per specificare il tipo di oggetto esportato. Questa riga è commentata, in modo da non impedire a Excel di aprire il file. Se non si desidera che vengano esportate le informazioni sul tipo, è sufficiente aggiungere il parametro -notype a Export-CSV. Inoltre, è possibile aggiungere il parametro -force per forzare la sovrascrittura di un file CSV esistente con lo stesso nome senza conferme (l'impostazione predefinita prevede una richiesta di conferma) oppure aggiungere il parametro -noClobber per evitare la sovrascrittura di un file esistente.

Per firmare gli script, è necessario un tipo specifico di certificato (un certificato Class III Authenticode Code-Signing) ed è possibile ottenerlo principalmente in tre modi. Il primo consiste nell'utilizzare l'infrastruttura a chiave pubblica, o PKI, interna dell'organizzazione se ne esiste una. Una PKI ben implementata prevede un certificato CA radice considerato attendibile da tutti i computer dell'organizzazione (questo è necessario perché i certificati emessi dall'autorità di certificazione siano utilizzabili nell'organizzazione).

Windows Server® viene fornito con un proprio software di server per certificati fin dai tempi di Windows® 2000 ed è possibile utilizzare tale software per creare una propria PKI. Un'implementazione completa di PKI richiede molta pianificazione, ma quando la PKI serve al solo scopo di emettere certificati di firma codice, non è necessario tanto lavoro. Si può utilizzare semplicemente Criteri di gruppo per inviare in modalità push il certificato CA radice ai computer dell'organizzazione, in modo che venga considerato attendibile.

Una seconda opzione consiste nell'utilizzare un'autorità di certificazione commerciale. Un vantaggio nell'utilizzo di un'autorità di certificazione commerciale è che, se si sceglie una delle autorità più presenti sul mercato, i computer dell'organizzazione sono probabilmente già configurati per accettare come attendibili i certificati dell'autorità di certificazione specifica. In Windows XP vengono accettati come attendibili molti certificati per impostazione predefinita, molti più che in Windows Vista®. Un'autorità di certificazione commerciale molto nota è VeriSign (verisign.com). Esistono altre aziende su cui vale la pena raccogliere ulteriori informazioni, come CyberTrust (cybertrust.com) e Thawte (thawte.com).

La terza opzione per ottenere un certificato di firma codice consiste nel crearsi da soli il proprio certificato utilizzando uno strumento come Makecert.exe. Lo strumento viene fornito con Windows Platform SDK, viene installato in alcune edizioni di Microsoft® Office e può essere trovato in molti altri luoghi. Il vantaggio di un certificato auto-firmato è che è gratuito e non richiede alcuna infrastruttura. Lo svantaggio, tuttavia, è che può essere davvero utilizzato solo sul computer su cui è stato generato. Ma se si tratta solo di attivare l'esecuzione di script sul proprio computer, per dei test o altri esperimenti con la firma del codice, Makecert.exe è un'ottima opzione. La documentazione su questo strumento è all'indirizzo go.microsoft.com/fwlink/?LinkId=108538. È però importante ricordare che, nel corso del tempo, si sono succedute molte versioni di questo strumento, quindi è possibile che sul computer si utilizzi già una versione meno recente che non funziona esattamente come descritto dalla documentazione.

Una volta ottenuto Makecert.exe, è possibile creare un certificato auto-firmato eseguendo del codice come il seguente dalla riga di comando di Windows PowerShell (si spera non più cmd.exe, almeno non i lettori di questo articolo):

makecert -n "CN=MyRoot" -a sha1 –eku
1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer 
–ss Root -sr localMachine

Quindi eseguire:

makecert -pe -n "CN=MyCertificate" -ss MY 
–a sh1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk 
–c root.cer

Makecert.exe chiede di immettere una password per proteggere la chiave, quindi viene creato il certificato. Si può verificare l'installazione eseguendo questo codice in Windows PowerShell:

gci cert:\CurrentUser\My -codesigning

Viene visualizzato un elenco di tutti gli elementi nel CERT: unità (ovvero l'archivio certificati di Windows) che sono certificati di firma codice. Tutto quanto qui esposto, è anche documentato in Windows PowerShell. Per trovare tale documentazione, eseguire help About_Signing e leggere le schermate visualizzate.

Firma di uno script

A questo punto esistono un certificato e uno script (a fine di test, se ne può creare rapidamente uno, se necessario), ovvero tutto il necessario per firmare uno script. Con Windows PowerShell è davvero molto facile. Immettere:

$cert = @(gci cert:\currentuser\my
-codesigning)[0]
Set-AuthenticodeSignature myscript.ps1 $cert

Con la prima parte si recupera il primo certificato di firma codice installato (se sono stati installati più certificati e si desidera utilizzarne uno diverso dal primo, sostituire "0" con il numero desiderato). Con la seconda parte si firma il file (ovviamente, si deve modificare il nome del file in modo che corrisponda al proprio). Tutto qui! A essere completamente onesti, tuttavia, bisogna dire che il nome del cmdlet Set-AuthenticodeSignature è un po' più lungo del necessario ed è per questo che è stato creato un alias denominato Sign. A questo punto, basta eseguire:

Sign myscript.ps1 $cert

Se si apre lo script, si noterà il blocco della firma inserito alla fine. Provare a eseguire lo script con i propri criteri di esecuzione impostati su AllSigned (Set-ExecutionPolicy AllSigned) e tutto funzionerà a dovere. Provare quindi a modificare lo script e salvarlo, senza firmarlo di nuovo. Windows PowerShell ora semplicemente si rifiuta di eseguire la versione modificata, perché la firma non è più valida.

Vale la pena

Ma alla fine ne vale davvero la pena? È chiedere troppo poter creare uno script con poche attività amministrative senza dover spendere 500 Dollari per un certificato o implementare un elemento di infrastruttura completamente nuovo? Dal punto di vista di un amministratore quale sono io, comprendo i dubbi che sono alla base di queste domande. Ma la risposta è semplice ed è che i vantaggi che si ottengono valgono decisamente lo sforzo fatto per ottenerli.

La sicurezza prevede sempre qualche fatica o problema aggiuntivo da affrontare e risolvere. Il software antivirus può creare fastidi, ma nessuno pensa di poterne fare a meno. I firewall software diventano spesso un ostacolo ma, come noto, non è consigliabile farne a meno. Anche Controllo dell'account utente di Windows Vista a volte è un impiccio, ma rende i computer più sicuri. E l'obiettivo di tutti noi non è proprio la massima sicurezza?

Windows PowerShell è uno strumento potente e, come per qualunque altro strumento, esiste sempre la possibilità che un utente malintenzionato lo utilizzi per i propri fini. È per questo motivo che è importante adottare ogni precauzione per rendere inoffensivi gli utenti malintenzionati.

La firma del codice è la soluzione migliore che si può adottare e non ha molte implicazioni. Io utilizzo, ad esempio, un editor di script grafico che firma automaticamente gli script ogni volta che salvo, quindi la firma del codice per me è praticamente trasparente.

È possibile renderlo altrettanto trasparente anche senza un editor elaborato. Si può creare, ad esempio, un profilo di Windows PowerShell (creare il file Microsoft.PowerShell_profile.ps1 in una cartella denominata WindowsPowerShell, che si trova sotto la cartella dei documenti) e aggiungere quindi questa funzione al profilo:

function sign ($filename) {
  $cert = @(gci cert:\currentuser\my 
-codesigning)[0]
Set-AuthenticodeSignature $filename $cert
}

Ora per firmare uno script è sufficiente immettere:

Sign c:\scripts\myscript.ps1

Ovviamente lo script del profilo sarà il primo a essere firmato. L'idea di fondo è eseguire poche operazioni che rendano quanto più comoda possibile la firma degli script, in modo che non risulti un fastidio.

La distribuzione di una PKI a server singolo con l'unico scopo di emettere un certificato di firma codice non è poi un gran lavoro. È utile ricordare, tuttavia, che è davvero necessario progettare una PKI che preveda la protezione del certificato CA radice e garantire il ripristino di emergenza, soprattutto se non sarà utilizzato per altri fini. Se il creatore degli script deve essere l'unico utente autorizzato a eseguire gli script nel proprio ambiente, è sempre disponibile Makecert.exe. L'argomento della guida di Windows PowerShell About_Signing contiene anche informazioni su come proteggere il certificato prodotto da Makecert.exe.

Don Jones è l'autore di Windows PowerShell: TFM and VBScript, WMI, and ADSI Unleashed. È possibile contattarlo tramite il sito Web PowerShellCommunity.org.

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