Windows PowerShellAssine aqui, por favor

Don Jones

Na coluna Windows PowerShell de janeiro de 2008, salientei a importância da assinatura digital de seus scripts do Windows PowerShell. E descrevi alguns cenários onde qualquer diretiva de execução diferente de AllSigned poderia criar vulnerabilidades de segurança significativas em seu ambiente.

Um assunto que não abordei em muitos detalhes é a forma como realmente assinar os seus scripts. Dê uma olhada na outra coluna em technetmagazine.com/issues/2008/01/PowerShell. Adivinhe sobre o que falarei neste mês?

Mais do que uma simples assinatura

A palavra assinatura é o termo técnico correto para o assunto sobre o qual estou falando, embora a palavra propriamente dita não seja uma boa descrição do que está acontecendo aqui. Assinar um script não significa que você o está aprovando ou autorizando, como o faria com um contrato ou com uma guia de cartão de crédito. No mundo da segurança digital, assinar é o processo de associar a sua identidade a algo e garantir que o estado ou condição desse "algo" não seja modificado de forma alguma. Tudo se baseia em criptografia, e a criptografia (pelo menos neste caso) começa com um par de chaves de criptografia.

Essas chaves são conhecidas como chaves assimétricas porque são diferentes uma da outra. O par consiste em uma chave privada, que só pode ser acessada por você, e em uma chave pública, que pode ser acessada por qualquer pessoa. Estou simplificando um pouco, mas basicamente qualquer coisa criptografada com a chave privada só poderá ser descriptografada com a chave pública correspondente.

Veja como funciona. Novamente, estou simplificando apenas para manter a discussão em andamento. Tenho um script Windows PowerShell® que desejo assinar e tenho um certificado que contém a minha chave privada que desejo usar para isso. O próprio Windows PowerShell possui um cmdlet, sobre o qual falarei em instantes, que pode obter o script e o certificado e executar a assinatura real. Quando faz isso, o Windows PowerShell obtém o script e o criptografa usando a minha chave privada. Essa cópia criptografada é exibida como texto sem sentido adicionado ao final do script como uma série de comentários (consulte a Figura 1). A minha identidade também é codificada, mas não criptografada, nesses comentários — a identidade propriamente dita pode ser lida sem que seja preciso recorrer à criptografia.

Figure 1 Bloco de assinatura no final do seu script

Figure 1** Bloco de assinatura no final do seu script **(Clique na imagem para aumentar a exibição)

Mais tarde, quando o Windows PowerShell ler a assinatura, decodificará a minha identidade e a usará para obter a minha chave pública. Uma vez que somente a minha chave pública pode descriptografar o resto da assinatura, o Windows PowerShell sabe que se ela é capaz de descriptografar a assinatura, então eu devo tê-la criado. Se outra pessoa tivesse assinado, a minha chave pública não seria capaz de descriptografar a assinatura. Depois que a assinatura é descriptografada, o Windows PowerShell compara o script à cópia que foi criptografada na assinatura. Se forem iguais, a assinatura será considerada intacta. Se os dois scripts forem diferentes, a assinatura será quebrada e considerada inválida.

Essa é a forma como uma assinatura protege um script não-criptografado de ser modificado sem que ninguém note. Lembre-se, enquanto o próprio script pode ser facilmente alterado, a assinatura não poderá ser alterada para coincidir com o script modificado sem o uso da minha chave privada — e somente eu tenho a minha chave privada.

Isso é definitivamente uma simplificação do processo técnico subjacente. Na realidade, as assinaturas podem e contêm mais informações, como uma cópia da minha chave pública, informações sobre a CA (autoridade de certificação) que emitiu as chaves, e assim por diante. Mas a minha descrição aqui certamente destaca as partes importantes do processo e realça o fato de que a assinatura na verdade protege você de modificações não autorizadas no script.

Um fator de segurança crítico é a proteção absoluta da sua chave privada — você não quer que ela caia nas mãos de outra pessoa. Quando instalar a sua chave no Windows, proteja-a imediatamente por senha para que um processo malicioso não a utilize sem o seu conhecimento. Os cartões inteligentes oferecem uma segurança ainda melhor, já que contêm a sua chave privada. A sua chave privada nunca deixará o cartão inteligente. Em vez disso, os dados que você deseja criptografar são transmitidos para o cartão por meio de seu hardware de leitura e o conjunto de circuitos do próprio cartão executará a criptografia e enviará o resultado de volta.

Obtendo um certificado

Cmdlet do mês: Export-CSV

Com freqüência, o pessoal que freqüenta os fóruns do site PowerShellCommunity.org pergunta se o Windows PowerShell pode ser exportado para o Microsoft Excel®. É claro que sim! O cmdlet Export-CSV executa esse truque, já que o Excel pode abrir, editar e salvar arquivos CSV de forma nativa. Por exemplo, se você quiser exportar uma lista de serviços, basta executar Get-Service | Export-CSV MeusServicos.csv. Na verdade, você pode inserir Export-CSV no final de qualquer pipeline e todos os objetos desse pipeline terminarão no arquivo CSV especificado. Por padrão, Export-CSV adiciona uma linha de cabeçalho ao início do arquivo, que será usada para especificar o tipo de objeto exportado. Essa linha é comentada para que não impeça que o Excel abra o arquivo. Se você não quiser que essas informações de tipo sejam exportadas, basta adicionar o parâmetro -notype a Export-CSV. Além disso, você pode adicionar o parâmetro -force para impor a substituição de um arquivo CSV existente com o mesmo nome sem confirmação (o padrão é a solicitação da confirmação) ou pode adicionar o parâmetro -noClobber para impedir a substituição de um arquivo existente.

Para assinar scripts, você precisará de um tipo específico de certificado — um certificado de assinatura de código Authenticode de Classe III — e existem três maneiras de obter um. A primeira é usar a PKI (Infra-Estrutura de Chave Pública) interna da sua organização, se houver uma. Uma PKI bem implementada fará com que todos os computadores da sua organização confiem na sua autoridade de certificação raiz — isso é necessário para que os certificados emitidos pela autoridade de certificação possam ser usados na organização.

O Windows Server® vem com seu próprio software de Servidor de Certificação desde o Windows® 2000, e você poderá usá-lo para criar a sua própria PKI. Uma implementação de PKI completa exige muito planejamento, mas se você simplesmente precisar de uma PKI para emitir certificados de assinatura de código, não terá toneladas de trabalho. Bastará usar uma Diretiva de Grupo para disponibilizar o seu certificado raiz da autoridade de certificação para todos os seus computadores para que eles confiem nele.

Uma segunda opção é usar uma autoridade de certificação comercial. Uma vantagem de usar uma é que, se você selecionar uma das principais autoridades de certificação, provavelmente os computadores da sua organização já estarão configurados para confiarem nos certificados emitidos por ela (observe que o Windows XP confia em um grande número delas por padrão, enquanto que o Windows Vista® confia em um número muito menor por padrão). Uma autoridade de certificação muito conhecida é a VeriSign (verisign.com). Existem outras que também merecem a sua atenção, como a CyberTrust (cybertrust.com) e a Thawte (thawte.com).

A terceira opção para a obtenção de um certificado de assinatura de código é criar o seu próprio certificado auto-assinado usando uma ferramenta como Makecert.exe. Ele vem com o SDK da Plataforma do Windows, pode ser instalado em algumas edições do Microsoft® Office e pode ser encontrado em vários outros locais. A vantagem de um certificado auto-assinado é que ele é gratuito e não exige infra-estrutura. A desvantagem, no entanto, é que ele só pode ser usado em seu computador. Mas se você simplesmente precisa habilitar a execução de scripts em seu computador — para testes ou experimentos gerais com assinatura de código — o Makecert.exe é uma ótima opção. A documentação dessa ferramenta pode ser encontrada em go.microsoft.com/fwlink/?LinkId=108538. Saiba que houve muitas versões dessa ferramenta nos últimos anos e, portanto, é possível que o seu computador esteja executando uma versão mais antiga que não funciona exatamente como descrito pela documentação.

Depois de obter o Makecert.exe, crie um certificado auto-assinado ao executar algo como o código a seguir na linha de comando do Windows PowerShell (e não me deixe pegar ninguém usando cmd.exe enquanto estiver lendo esta coluna):

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

E depois execute o seguinte comando:

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

O Makecert.exe solicitará uma senha para a proteção da chave e criará certificado. Você pode verificar a instalação executando este código no Windows PowerShell:

gci cert:\CurrentUser\My -codesigning

Isso exibirá uma lista de todos os itens da unidade CERT: (que é o armazenamento de certificados do Windows) que são certificados de assinatura de código. Aliás, tudo isso também está documentado no próprio Windows PowerShell. Para localizar essa documentação, basta executar a ajuda de About_Signing e ler algumas telas.

Assinando um script

Agora que você tem um certificado e um script (para fins de teste, basta criar um rapidamente, se necessário), está pronto para assinar o script. Isso é extremamente fácil com o Windows PowerShell — basta digitar:

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

A primeira parte recupera o primeiro certificado de assinatura de código instalado (se você tiver vários certificados instalados e se quiser usar algum diferente do primeiro, basta alterar o "0" pelo número apropriado). A segunda parte assina o arquivo (é claro, você terá de alterar o nome do arquivo para ficar igual ao seu). É simples assim! No entanto, para ser totalmente honesto, acho que o nome do cmdlet Set-AuthenticodeSignature é um pouco mais longo do que o necessário e é por isso que criei um alias chamado Sign. Agora, basta executar:

Sign myscript.ps1 $cert

Abra esse script para ver o bloco de assinatura inserido no final. Tente executar o script com a sua diretiva de execução definida como AllSigned (Set-ExecutionPolicy AllSigned) e tudo deve funcionar bem. Modifique o script, se quiser, e salve-o, mas não o assine novamente. Agora, o Windows PowerShell deve simplesmente se recusar a executar a versão modificada, uma vez que a assinatura foi quebrada.

Vale o esforço

Isso realmente vale todo esse trabalho? Seria pedir muito ser capaz de criar um script com algumas tarefas administrativas sem ter de gastar US$ 500 em um certificado ou implementar todo um novo elemento de infra-estrutura? Veja, eu sou um administrador também e compreendo as suas preocupações. Mas a resposta simples é que isso definitivamente vale cada pedacinho de esforço exigido.

O fato é que a segurança quase sempre envolve algum nível de trabalho. O software antivírus pode ser um saco, mas você não vive sem ele. O software de firewall é definitivamente um problema, mas como você sabe, não é seguro viver sem um firewall. E o UAC (Controle de Conta de Usuário) do Windows Vista também pode ser um problema, mas torna o seu computador mais seguro. E essa não é a segurança aprimorada que todos nós estamos tentando obter?

O Windows PowerShell é uma ferramenta poderosa e, como qualquer outra ferramenta, sempre há o risco de ser envolvida em uma vulnerabilidade de segurança por um usuário malicioso. É por isso que é importante que você tome providências para impedir esses usuários maliciosos.

A assinatura de código é a melhor providência a ser tomada e não exige muito envolvimento. Por exemplo, eu uso um editor gráfico de scripts que assina automaticamente os meus scripts sempre que eu pressiono Salvar e, portanto, a assinatura de código é bastante transparente para mim.

Você pode torná-la ainda mais transparente, mesmo sem um editor luxuoso. Por exemplo, você pode criar um perfil do Windows PowerShell para si mesmo (crie o arquivo Microsoft.PowerShell_profile.ps1 em uma pasta chamada WindowsPowerShell, localizada em sua pasta de documentos) e adicione esta função a ele:

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

Agora é possível assinar os seus scripts simplesmente digitando:

Sign c:\scripts\myscript.ps1

É claro que esse script de perfil deve ser o primeiro a ser assinado! A idéia é tomar algumas providências para tornar a assinatura de script tão conveniente quanto possível, para que ela não seja um problema.

A implantação de uma PKI de um servidor para o único propósito de emitir um certificado de assinatura de código não significa muito trabalho (no entanto, tenha em mente que você realmente precisa pesquisar e planejar a sua PKI, incluindo a proteção da autoridade de certificação raiz e o fornecimento de recuperação de desastres, especialmente se ela for usada para algo mais). O Makecert.exe sempre estará disponível se você for o único a executar scripts em seu ambiente. Observe que o tópico da ajuda About_Signing do Windows PowerShell também inclui informações sobre a proteção do certificado produzido pelo Makecert.exe.

Don Jones é o autor de Windows PowerShell: TFM and VBScript, WMI, and ADSI Unleashed. Você pode entrar em contato com ele pelo site PowerShellCommunity.org.

© 2008 Microsoft Corporation e CMP Media, LLC. Todos os direitos reservados. A reprodução parcial ou completa sem autorização é proibida..