PowerShell スクリプトの署名

I ❤️ PowerShell. PowerShell は、何度も行う作業を自動化するのにとても便利なツールです。 しかし、放っておくと、セキュリティホールになることもあります。

PowerShell を使用すると、マシン上のほぼすべてのものを管理できるため、悪意のあるスクリプトを環境内で実行できる人がいると、多くの被害が発生します。 しかし、この記事では、Windows 以外の環境では変更できない実行ポリシーについて説明しているため、Linux/MacOS ユーザーには何のメリットもありません (申し訳ありません)。

実行ポリシー

Windows 環境でのスクリプトの実行を制限する方法の1つは、PowerShell の実行ポリシーを使用することです。 このポリシーは、環境内で実行されるスクリプトを制限するために使用されます。

Bypass

Nothing is blocked.

Unrestricted (Non-Windows マシンで常に適用)

ByPass と同じですが、インターネットからスクリプトを実行する前にユーザーにプロンプトが表示されます。

RemoteSigned (Windows Servers のデフォルト)

インターネットからダウンロードされたスクリプトは、署名されている場合のみ実行可能です。 マシン上に書かれたスクリプトは実行できます

AllSigned

すべてのスクリプトは、実行する前に署名する必要があります

Restricted (Windows Client の既定)

スクリプトを実行できなくなりました。

スクリプトの実行

では、サーバー上で独自の PowerShell スクリプトを実行したいとします。 しかし、次のようなPSSecurityExceptionが表示されます。

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
Enter fullscreen mode Exit fullscreen mode

この問題を解決する方法の1つは、Set-ExecutionPolicyコマンドを使って実行ポリシーを変更することとマシンのセキュリティを低下させることです。 これは一般的に悪い考えです。

個人的には、サーバー上で RemoteSigned よりも安全でないものは使用しませんが、理想的には AllSigned です。

スクリプト署名とは何ですか。

おそらく、マシンのセキュリティを維持したい、脆弱性を開いたくないので、あなたに残された選択肢は、あなたのスクリプトに署名することです。

スクリプトに署名するということは、コード署名証明書のプライベート キーにアクセスできる誰かが、スクリプト ファイルの末尾に署名ブロックを追加したことを意味します。

function Get-Wibble { return "Wibble"}# SIG # Begin signature block# vpnIUpm2XxLRhU1no0iuA62xKxYzR6m95z9Ax21ppeTC9NoRd8ocoSGr1zAd# qlMOlz4lZoVWR4ZmtdCgzde1dVxzv4jjHb6ziDiY2o05UXswD2bl6XaOrUpd# Li0Qjg3d3y2r1nrpO8hos906bgXQswysvouegUJcpt8ftmqBKfEYNeBgnBFm# SIG # End signature block
Enter fullscreen mode Exit fullscreen mode

(example only. the signature block is usually much longer)

署名ブロックは、プライベートキーを使用して暗号化されているスクリプトのハッシュを含んでいます。 スクリプトを実行しようとすると、公開鍵を使用してこれが復号化され、実際のハッシュと比較されます。

自己署名証明書

スクリプトが組織内のマシンによってのみ実行される場合、ほとんどの場合、自己署名証明書を使用できます。

自己署名とは、自分で証明書を生成し、それを使用してスクリプトに署名することです。

自己署名証明書の作成方法

PowerShell には、自己署名証明書を生成する非常に便利な New-SelfSignedCertificate コマンドがあります。 デフォルトでは、このコマンドは 1 年後に期限切れになる証明書を作成します。

証明書を作成するには、PowerShell セッションを起動して、次のように実行します。

$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"
Enter fullscreen mode Exit fullscreen mode

これにより、証明書が作成されて、拡張子が .pfx および .cer の 2 つの別々のファイルにエクスポートされます。

PFX

PFX 証明書は、署名を行うマシンにインストールする必要がある証明書です。

これは、「信頼されたルート認証局」ストアとして知られる cert:\CurrentUser\Root ストアにインストールする必要があります。 その後、パスワードは別に保護する必要があります (パスワード マネージャーを使用します)。 悪質な業者がこの両方を手に入れた場合、悪意のあるスクリプトに、あたかも自分であるかのように署名することができます。

CER

CER 証明書ファイルは、スクリプトを実行するマシンにインストールする必要があるものです。 これはインストールにパスワードを必要としませんが、スクリプトに署名するために使用することはできません。

秘密鍵が含まれていないため、この証明書はスクリプトを実行するすべての環境に自由に配布できます。

これは、スクリプトを実行するマシンの cert:\LocalMachine\Root および cert:\LocalMachine\TrustedPublisher という 2 つの証明書ストアにインストールする必要があります。 スクリプトへのパスとストアからの証明書を渡す必要があります。 スクリプトに署名できるラッパー関数を書きました。

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

$certificateName変数に証明書を作成するときに使用した名前を格納してください。

スクリプトを含むディレクトリへのパスを指定することでこの機能を使用でき、スクリプトをループしてすべてに署名します。

ターゲット マシンにスクリプトをインストールしたら、問題なくスクリプトを実行できるはずです。

コメントを残す

メールアドレスが公開されることはありません。