Assinando scripts PowerShell

I ❤️ PowerShell. É uma ferramenta realmente útil para automatizar aquelas tarefas que você faz várias vezes. Mas também pode ser uma falha de segurança se o deixar.

PowerShell permite-lhe administrar quase tudo na sua máquina, por isso há muitos danos que podem ser feitos por alguém capaz de executar scripts maliciosos nos seus ambientes.

Anteriormente confinado apenas ao Windows, desde a versão 6 e agora com o lançamento do PowerShell 7.0, também pode ser implementado em Linux e MacOS. No entanto, este artigo fala sobre Políticas de Execução que não podem ser alteradas em ambientes que não sejam Windows, por isso não irá proporcionar nenhum benefício aos utilizadores de Linux/MacOS (desculpe).

Políticas de Execução

Uma forma de restringir a capacidade de executar scripts nos seus ambientes Windows é usar as políticas de execução do PowerShell. A tldr é que elas podem ser usadas para restringir os scripts que serão executados no ambiente. As opções disponíveis do menos seguro ao mais seguro são:

Bypass

Nada é bloqueada.

Ilimitada (Aplica-se sempre em máquinas sem Windows)

O mesmo que ByPass mas avisa o utilizador antes de executar scripts a partir da Internet.

RemoteSigned (padrão para Servidores Windows)

Scripts que foram baixados da internet só podem ser executados se estiverem assinados. Scripts escritos na máquina podem ser executados

AllSigned

Todos os scripts devem ser assinados antes de serem executados

Restrito (padrão para Clientes Windows)

Previne que os scripts sejam executados. Só pode executar comandos individuais.

Executar Scripts

Então você quer executar seus próprios scripts PowerShell no seu servidor. Mas você está recebendo um PSSecurityException como o seguinte.

PS C:\Users\Administrator\Downloads> .\wibble.ps1.\wibble.ps1 : File .\wibble.ps1 cannot be loaded. The file.\wibble.ps1 is not digitally signed. You cannot run this script on the current system.For more information about running scripts and setting execution policy, see about_Execution_Policies athttp://go.microsoft.com/fwlink/?LinkID=135170.At line:1 char:1+ .\wibble.ps1+ ~~~~~~~~~~~~ + CategoryInfo : SecurityError: (:) , PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess
Entre no modo tela cheia Sair do modo tela cheia

Uma maneira de resolver este problema é mudar a política de execução usando o comando Set-ExecutionPolicy e reduzir a segurança da máquina. Esta é geralmente uma má idéia.

Pessoalmente, eu nunca usaria nada menos seguro que RemoteSigned num servidor, mas AllSigned idealmente.

O que é uma assinatura de script?

Presumivelmente você quer manter a segurança da máquina e não abrir uma vulnerabilidade, então a opção deixada para você é assinar seus scripts.

Assinar um script significa que alguém com acesso à chave privada para um certificado de assinatura de código adicionou um bloco de assinatura no final do arquivo do script.

function Get-Wibble { return "Wibble"}# SIG # Begin signature block# vpnIUpm2XxLRhU1no0iuA62xKxYzR6m95z9Ax21ppeTC9NoRd8ocoSGr1zAd# qlMOlz4lZoVWR4ZmtdCgzde1dVxzv4jjHb6ziDiY2o05UXswD2bl6XaOrUpd# Li0Qjg3d3y2r1nrpO8hos906bgXQswysvouegUJcpt8ftmqBKfEYNeBgnBFm# SIG # End signature block
Entre no modo ecrã completo Sair do modo ecrã completo

(Apenas como exemplo. O bloco de assinatura é normalmente muito mais longo)

O bloco de assinatura conterá um hash do script que foi encriptado utilizando a chave privada. Ao tentar executar o script isto é descriptografado usando a chave pública e comparado com o hash real. Se corresponder, então podemos confirmar que o script não foi adulterado, pois o hash mudaria assim que isso acontecesse.

Certificados de Auto Assinatura

Se os seus scripts só vão ser executados por máquinas da sua organização, então o mais provável é que consiga autoassinar os certificados. A alternativa é gastar $$$ e comprar um certificado de assinatura de código a cada ano.

Self signing significa que você mesmo irá gerar o certificado e assinar os scripts usando isso.

Como criar um certificado de autoassinatura

PowerShell tem o comando muito útil New-SelfSignedCertificate para produzir certificados autoassinados. Podemos então exportá-los e colocá-los em diferentes lojas.

Por padrão o comando irá criar um certificado que expira após 1 ano. Pode alterar isto utilizando o parâmetro -NotAfter e fornecendo-lhe a data em que pretende que o certificado expire.

Para criar um certificado dispara uma sessão PowerShell e correr o seguinte

$CertificateName = Read-Host "Input your certificate name"$OutputPFXPath = "$CertificateName.pfx"$OutputCERPath = "$CertificateName.cer"$Password = Get-Credential -UserName Certificate -Message "Enter a secure password:"$certificate = New-SelfSignedCertificate -subject $CertificateName -Type CodeSigning -CertStoreLocation "cert:\CurrentUser\My"$pfxCertificate = Export-PfxCertificate $certificate -FilePath $OutputPFXPath -password $Password.passwordExport-Certificate -Cert $certificate -FilePath $OutputCERPathImport-PfxCertificate $pfxCertificate -CertStoreLocation cert:\CurrentUser\Root -Password $password.passwordWrite-Output "Private Certificate '$CertificateName' exported to $OutputPFXPath"Write-Output "Public Certificate '$CertificateName' exported to $OutputCERPath"
Entrar no modo ecrã completo Sair do modo ecrã completo

Isto irá criar o certificado e exportá-lo para dois ficheiros separados com as extensões .pfx e .cer.

PFX

O certificado PFX é o que terá de ser instalado nas máquinas que irão fazer a assinatura. No nosso caso é cada uma das nossas máquinas de desenvolvimento.

Deve ser instalado na loja cert:\CurrentUser\Root, também conhecida como a loja “Trusted Root Certification Authorities”.

Este arquivo deve ser mantido em algum lugar seguro. A senha deve então ser protegida separadamente (use um gerenciador de senha). Se um ator mau pegar os dois então eles podem assinar seus scripts maliciosos como se fossem você.

CER

O arquivo CER certificado é o que você terá que instalar nas máquinas que estarão rodando os scripts. Isto não requer uma senha para instalar mas não pode ser usado para assinar os scripts. Ele apenas contém a chave pública utilizada para desencriptar a assinatura.

Porque não contém a chave privada este certificado pode ser distribuído livremente para todos os ambientes que irão correr os scripts.

Esta terá de ser instalada em duas lojas de certificados nas máquinas que irão correr os scripts; As cert:\LocalMachine\Root e cert:\LocalMachine\TrustedPublisher lojas.

Assinar um script

A função Set-AuthenticodeSignature é fornecida para assinar os scripts. Precisamos de passar no caminho para o script e para o certificado da loja. Nós escrevemos uma função wrapper que pode assinar os scripts.

function Set-ScriptSignatures { param ( $pathToScripts = "." ) $certificateName = "PowerShell Signing Certificate" $scripts = Get-ChildItem -Path "$pathToScripts\*" -Include *.ps1, *.psm1 -Recurse $certificate = @(Get-ChildItem cert:\CurrentUser\My -codesign | Where-Object { $_.issuer -like "*$certificateName*" } ) foreach ($script in $scripts) { Write-Host "Signing $script" Set-AuthenticodeSignature $script -Certificate $certificate }}
Enter fullscreen mode Exit fullscreen mode

A variável $certificateName deve conter o nome usado na criação do certificado.

Pode usar a função fornecendo um caminho para o directório que contém os scripts e irá passar por eles assinando-os todos.

Após ter instalado os scripts na máquina de destino deverá agora ser capaz de executar os scripts sem quaisquer problemas.

Deixe uma resposta

O seu endereço de email não será publicado.