Como Assinar um Script do PowerShell (E Executá-lo Efetivamente)

Você precisa garantir que ninguém faça modificações em seus scripts e os passe como originais? Se sim, então você precisa aprender a assinar scripts do PowerShell. A assinatura adiciona a identidade do editor ao script para que os usuários possam decidir se confiam na fonte do script.

Neste artigo, aprenda como garantir que apenas scripts confiáveis sejam executados em seu ambiente, aprendendo como assinar scripts do PowerShell.

Pré-requisitos

Se você pretende seguir os exemplos deste artigo, você precisa do seguinte.

  • A computer running on a recent version of the Windows operating system. This article uses Windows 10 version 20H2.
  • Windows PowerShell 5.1 ou PowerShell 6+. Os exemplos neste artigo usarão o PowerShell v7.1.3.
  • A sample PowerShell script for signing. Feel free to create a script with any name and in any folder you want. This article will use a sample script called C:\ATA\myscript.ps1 that contains the code below.
Write-Host "Script Execution - OK"

Obtendo um Certificado de Assinatura de Código

Antes de aprender como assinar um script do PowerShell, você precisa obter um certificado de assinatura de código primeiro. No mundo da Microsoft, os certificados de assinatura de código também são conhecidos como certificados Authenticode.

A code signing certificate is one type of digital certificate whose purpose for signing files. Signing a file or code with a code signing certificate adds proof that the file came from the publisher who signed it.

Onde você obtém um certificado de assinatura de código depende de onde pretende implantar ou distribuir seus scripts assinados. E, como sempre, o custo também é um fator importante.

  • Global / Público – Você precisará de um certificado cujo emissor seja uma Autoridade de Certificação (AC) globalmente confiável. Exemplos de tais ACs são GeoTrust e DigiCert. Esses certificados não são gratuitos. Por exemplo, um certificado Authenticode da DigiCert custará $474/ano no momento desta redação.
  • Interno / Intranet Local – Se você tiver um servidor de Autoridade de Certificação (AC) interno, pode solicitar e baixar um certificado de assinatura do seu servidor de AC interno.
  • Pessoal / Desenvolvimento – Para testes pessoais ou uso de desenvolvimento, um certificado autoassinado deve ser suficiente. Este é o tipo de certificado de assinatura que você usará neste artigo.

Criando um Certificado Autoassinado para Assinatura de Código

Você leu na seção anterior que, ao aprender a assinar scripts do PowerShell, você primeiro precisa de um certificado de assinatura de código. Como você estará fazendo apenas testes pessoais neste tutorial, um certificado autoassinado será suficiente. Mas onde você o obtém?

Como o nome sugere, autoassinado significa que seu computador local emitirá um certificado de assinatura de código para si mesmo. Para gerar um certificado autoassinado, siga estas etapas.

1. Abra o PowerShell como administrador no seu computador.

2. Copie o comando abaixo e execute no PowerShell. Este comando utiliza o cmdlet New-SelfSignedCertificate para criar um novo certificado de assinatura de código. O nome do certificado é ATA Authenticode dentro do repositório de certificados pessoais do computador local.

O cmdlet New-SelfSignedCertificate suporta apenas a criação de certificados no repositório de certificados pessoais do usuário atual (cert:\CurrentUser\My) ou no repositório de certificados pessoais da máquina local (cert:\LocalMachine\My). Certificados em cert:\LocalMachine\My estão disponíveis em todo o computador.

O comando também armazena o objeto do certificado na variável $authenticode para uso na próxima etapa.

# Gere um certificado Authenticode autoassinado no repositório de certificados pessoais do computador local.
 $authenticode = New-SelfSignedCertificate -Subject "ATA Authenticode" -CertStoreLocation Cert:\LocalMachine\My -Type CodeSigningCert

3. Em seguida, para fazer com que o seu computador confie no novo certificado que você criou, adicione o certificado autoassinado aos repositórios de certificados Autoridade de Certificação Raiz Confiável e Editoras Confiáveis do computador. Para fazer isso, copie o código abaixo e execute no PowerShell.

# Adicione o certificado Authenticode autoassinado à loja de certificados raiz do computador.
## Crie um objeto para representar a loja de certificados LocalMachine\Root.
 $rootStore = [System.Security.Cryptography.X509Certificates.X509Store]::new("Root","LocalMachine")
## Abra a loja de certificados raiz para leitura e gravação.
 $rootStore.Open("ReadWrite")
## Adicione o certificado armazenado na variável $authenticode.
 $rootStore.Add($authenticode)
## Feche a loja de certificados raiz.
 $rootStore.Close()
 
# Adicione o certificado Authenticode autoassinado à loja de certificados de editores confiáveis do computador.
## Crie um objeto para representar a loja de certificados LocalMachine\TrustedPublisher.
 $publisherStore = [System.Security.Cryptography.X509Certificates.X509Store]::new("TrustedPublisher","LocalMachine")
## Abra a loja de certificados TrustedPublisher para leitura e gravação.
 $publisherStore.Open("ReadWrite")
## Adicione o certificado armazenado na variável $authenticode.
 $publisherStore.Add($authenticode)
## Feche a loja de certificados TrustedPublisher.
 $publisherStore.Close()

Há três razões principais para instalar os certificados autoassinados em três lojas de certificados diferentes.

  • O certificado que você criou na loja de certificados Personal é o que você usará como certificado de assinatura de código.
  • Copiando o mesmo certificado para a loja de editores confiáveis garante que seu computador local confiará no editor que assinou o script. O PowerShell verifica o certificado nesta loja para validar a assinatura de um script.
  • Finalmente, adicionar o certificado autoassinado às Autoridades de Certificação Raiz Confiáveis garante que o seu computador local confie nos certificados armazenados nas lojas Pessoal e Editores Confiáveis.

4. Para confirmar que o certificado com o assunto ATA Authenticode está nas lojas de certificados Pessoal, Raiz e Editores Confiáveis, execute os comandos abaixo no PowerShell.

# Confirmar se o certificado Authenticode autoassinado existe na loja de certificados Pessoal do computador
 Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
# Confirmar se o certificado Authenticode autoassinado existe na loja de certificados Raiz do computador
 Get-ChildItem Cert:\LocalMachine\Root | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
# Confirmar se o certificado Authenticode autoassinado existe na loja de certificados Editores Confiáveis do computador
 Get-ChildItem Cert:\LocalMachine\TrustedPublisher | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
Confirming the creation of the new self-signed certificate

5. Para visualizar o certificado em uma interface gráfica, abra o Snap-in de Certificados e procure o certificado que você criou nas pastas Certificados dentro das lojas de certificados Pessoal, Autoridades de Certificação Raiz Confiáveis, e Editores Confiáveis.

Viewing certificates in the Microsoft Management Console (MMC)

Como Assinar Scripts do PowerShell

Agora que você criou e instalou seu certificado de assinatura de código nos três repositórios de certificados, você está pronto para usá-lo para assinar seu script de exemplo do PowerShell. Quando precisar assinar scripts, o cmdlet Set-AuthenticodeSignature é a estrela principal.

Para assinar o script do PowerShell, execute o código abaixo no PowerShell. O primeiro comando obtém o certificado de assinatura de código do repositório de certificados pessoais da máquina local. O segundo comando adiciona uma assinatura digital ao arquivo do script do PowerShell.

# Obter o certificado de assinatura de código do repositório de certificados da máquina local com o nome *ATA Authenticode* e armazená-lo na variável $codeCertificate.
$codeCertificate = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}

# Assinar o script do PowerShell
# PARÂMETROS:
# FilePath - Especifica o caminho do arquivo do script do PowerShell a ser assinado, por exemplo, C:\ATA\myscript.ps1.
# Certificate - Especifica o certificado a ser usado ao assinar o script.
# TimeStampServer - Especifica o servidor de carimbo de data/hora confiável que adiciona um carimbo de data/hora à assinatura digital do seu script. Adicionar um carimbo de data/hora garante que seu código não expirará quando o certificado de assinatura expirar.
Set-AuthenticodeSignature -FilePath C:\ATA\myscript.ps1 -Certificate $codeCertificate -TimeStampServer *<http://timestamp.digicert.com>*

A maioria dos provedores de certificados confiáveis tem um servidor de carimbo de data e você pode encontrá-los nos sites dos provedores. Por exemplo, o servidor de carimbo de data da DigiCert é http://timestamp.digicert.com e a Comodo tem http://timestamp.comodoca.com.

Depois de assinar o script, você deverá ver uma saída semelhante à captura de tela abaixo.

How to Sign PowerShell Scripts

Verificando a Assinatura Digital de um Script do PowerShell

Até agora, você assinou um script do PowerShell usando o certificado autoassinado que você criou. Mas como você sabe se o script realmente tem uma assinatura digital?

Abrindo o Código

Uma maneira de confirmar a assinatura digital de um script é abrir o script e visualizar o código em um editor de texto. Como no exemplo abaixo, o script assinado tem um bloco de assinatura no final do código. O bloco de assinatura começa com # SIG # Begin signature block e termina com # SIG # End signature block.

Viewing the digital signature in the script’s content

Excluir o bloco de assinatura digital do código do script fará com que o script volte a ser não assinado.

Abrindo as Propriedades do Arquivo do Script

Outra maneira de verificar a assinatura digital do script é abrir as propriedades do arquivo do script no Windows Explorer. Para fazer isso:

  1. No Windows Explorer, navegue até o local do script do PowerShell. Neste exemplo, o script está em C:\ATA\myscript.ps1.
  2. Clique com o botão direito no script e clique em Propriedades.
  3. Na janela de Propriedades do arquivo, clique na guia Assinaturas Digitais, e você deverá ver uma assinatura digital na lista de assinaturas.
Viewing the digital signature in the script’s file properties

Usando Get-AuthenticodeSignature

Você ficaria surpreso ao saber que também pode verificar a assinatura de um script dentro do PowerShell? Provavelmente não. O cmdlet que você pode invocar para recuperar a assinatura de um arquivo é Get-AuthenticodeSignature.

Para obter a assinatura digital do script, execute o comando abaixo. Este comando obtém a assinatura do arquivo C:\ATA\myscript.ps1. O cmdlet Select-Object -Property * exibe todos os detalhes da assinatura.

Get-AuthenticodeSignature -FilePath C:\\ATA\\myscript.ps1 | Select-Object -Property *

Após executar o comando, você deverá ver um resultado semelhante ao capturado na tela abaixo. Como pode ser visto, a propriedade SignerCertificate mostra os detalhes do certificado de assinatura. Enquanto a propriedade TimerStamperCertificate mostra o certificado do servidor de carimbo de data e hora.

Viewing the digital signature in PowerShell

Executando um Script do PowerShell Assinado

Neste ponto, você assinou um script do PowerShell e confirmou que a assinatura digital está presente. Mas, o teste final para saber se você seguiu todos os passos corretamente é executar o script e confirmar que ele funciona.

O PowerShell possui um recurso de segurança que protege os usuários de executar scripts inadvertidamente. Esse recurso de segurança é chamado Políticas de Execução. Dependendo da política de execução, o PowerShell pode impedir ou permitir a execução de scripts.

Para aprender sobre as diferentes políticas de execução e como elas afetam a execução de scripts, consulte Políticas de Execução do PowerShell: Compreensão e Gerenciamento.

Para executar um script do PowerShell assinado, siga estas etapas.

Primeiro, altere a política de execução para AllSigned para garantir que apenas scripts assinados possam ser executados. Sem fazer este passo, você não pode testar com precisão se o seu script assinado funciona. Para fazer isso, invoque o cmdlet Set-ExecutionPolicy executando o comando abaixo no PowerShell como administrador.

Set-ExecutionPolicy AllSigned

Em seguida, execute o script do PowerShell assinado.

C:\ATA\myscript.ps1

O script deve ser executado sem erros ou avisos, como você pode ver no resultado abaixo.

Running the signed script without errors

Mas, se por algum motivo o script não estiver corretamente assinado ou não estiver assinado de todo, você receberá um erro semelhante à imagem abaixo. Nesse caso, revise seus passos e tente assinar o script novamente.

Running a script with errors regarding the digital signature

E se você eventualmente atualizou seu script? A assinatura digital ainda será válida? A resposta é não. Qualquer modificação no script assinado invalidará a assinatura digital do script. Executar o script modificado falhará e resultará em um erro.

Siga estas etapas para testar um script assinado modificado.

1. Abra o script assinado myscript.ps1 em um editor de código ou texto.

2. Modifique o código para adicionar um caractere, como um sublinhado neste exemplo. Não altere mais nada.

Editing the signed script

3. Salve o script após modificar o código.

4. Por fim, execute o script modificado no PowerShell executando o comando abaixo.

C:\ATA\myscript.ps1

Como você modificou o script assinado, a execução do script resultará no erro mostrado abaixo. Você precisará assinar o script novamente para atualizar e corrigir sua assinatura digital.

Running a signed script with a broken digital signature

A digital signature does not guarantee that nobody modified the script from its original version. Any PowerShell script with malicious code may be digitally signed, too. Always practice caution when running scripts from sources you do not fully trust.

Conclusão

Neste artigo, você aprendeu por que assinar scripts do PowerShell pode ser necessário dependendo das políticas de execução. Você também aprendeu como distinguir entre um script assinado e não assinado. Finalmente, você aprendeu como assinar scripts do PowerShell digitalmente e como testá-los e executá-los.

Agora que você sabe como assinar scripts do PowerShell, vai começar a assinar scripts antes de distribuí-los ou implantá-los?

Source:
https://adamtheautomator.com/how-to-sign-powershell-script/