Как подписать сценарий PowerShell (и эффективно запустить его)

Вам необходимо убедиться, что никто не вносит изменений в ваши сценарии и не передает их как оригинальные? В этом случае вам необходимо научиться подписывать сценарии PowerShell. Подпись добавляет идентификатор издателя к сценарию, чтобы пользователи могли решить, доверять ли источнику сценария.

В этой статье вы узнаете, как гарантировать, что в вашей среде выполняются только доверенные сценарии, научившись подписывать сценарии PowerShell.

Предварительные требования

Если вы собираетесь следовать примерам в этой статье, вам понадобится следующее.

  • A computer running on a recent version of the Windows operating system. This article uses Windows 10 version 20H2.
  • Windows PowerShell 5.1 или PowerShell 6+. Примеры в этой статье будут использовать 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"

Получение сертификата цифровой подписи

Прежде чем научиться подписывать сценарий PowerShell, вам необходимо получить сертификат цифровой подписи. В мире Microsoft сертификаты цифровой подписи также известны как Сертификаты 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.

Где вы получите сертификат цифровой подписи зависит от того, где вы собираетесь развернуть или распространять ваши подписанные сценарии. И, как всегда, стоимость также является важным фактором.

  • Глобальный / Публичный – Вам понадобится сертификат, выпущенный всемирно доверенным Центром сертификации (CA). Примеры таких ЦС включают GeoTrust и DigiCert. Эти сертификаты не бесплатны. Например, на момент написания этого текста сертификат Authenticode от DigiCert будет стоить $474 в год.
  • Внутренний / Локальная интранет – Если у вас есть внутренний сервер центра сертификации (CA), вы можете запросить и загрузить подписанный сертификат с вашего внутреннего сервера CA.
  • Личный / Разработка – Для личного тестирования или разработки подойдет самоподписанный сертификат. Именно этот тип подписанного сертификата вы будете использовать в этой статье.

Создание самоподписанного сертификата для подписи кода

Вы уже читали в предыдущем разделе, что для подписания сценария PowerShell сначала вам понадобится сертификат для подписи кода. Поскольку в этом учебнике вы будете проводить только личное тестирование, подойдет самоподписанный сертификат. Но где его взять?

Как следует из названия, самоподписанный означает, что ваш компьютер будет выдавать самому себе сертификат для подписи кода. Чтобы создать самоподписанный сертификат, выполните следующие шаги.

1. Откройте PowerShell от имени администратора на своем компьютере.

2. Скопируйте команду ниже и выполните ее в PowerShell. Эта команда использует cmdlet New-SelfSignedCertificate для создания нового сертификата подписи кода. Имя сертификата – ATA Authenticode в хранилище сертификатов Личного компьютера.

Команда New-SelfSignedCertificate поддерживает создание сертификатов только в личном хранилище текущего пользователя (cert:\CurrentUser\My) или в личном хранилище локального компьютера (cert:\LocalMachine\My). Сертификаты в cert:\LocalMachine\My доступны на всем компьютере.

Кроме того, команда сохраняет объект сертификата в переменной $authenticode для использования на следующем этапе.

# Сгенерировать самоподписанный сертификат Authenticode в локальном хранилище сертификатов компьютера.
 $authenticode = New-SelfSignedCertificate -Subject "ATA Authenticode" -CertStoreLocation Cert:\LocalMachine\My -Type CodeSigningCert

3. Затем, чтобы ваш компьютер доверял новому созданному сертификату, добавьте самоподписанный сертификат в хранилище сертификатов Доверенных корневых удостоверяющих центров и Доверенных издателей. Для этого скопируйте код ниже и выполните его в PowerShell.

# Добавьте самоподписанный сертификат Authenticode в хранилище корневых сертификатов компьютера.
## Создайте объект для представления хранилища сертификатов LocalMachine\Root.
 $rootStore = [System.Security.Cryptography.X509Certificates.X509Store]::new("Root","LocalMachine")
## Откройте хранилище корневых сертификатов для чтения и записи.
 $rootStore.Open("ReadWrite")
## Добавьте сертификат, хранящийся в переменной $authenticode.
 $rootStore.Add($authenticode)
## Закройте хранилище корневых сертификатов.
 $rootStore.Close()
 
# Добавьте самоподписанный сертификат Authenticode в хранилище сертификатов доверенных издателей компьютера.
## Создайте объект для представления хранилища сертификатов LocalMachine\TrustedPublisher.
 $publisherStore = [System.Security.Cryptography.X509Certificates.X509Store]::new("TrustedPublisher","LocalMachine")
## Откройте хранилище сертификатов TrustedPublisher для чтения и записи.
 $publisherStore.Open("ReadWrite")
## Добавьте сертификат, хранящийся в переменной $authenticode.
 $publisherStore.Add($authenticode)
## Закройте хранилище сертификатов TrustedPublisher.
 $publisherStore.Close()

Есть три основных причины установки самоподписанных сертификатов в три различных хранилища сертификатов.

  • Сертификат, созданный в хранилище Personal, предназначен для использования в качестве сертификата подписи кода.
  • Копирование того же сертификата в хранилище Trusted Publishers гарантирует, что ваш компьютер будет доверять издателю, подписавшему скрипт. PowerShell проверяет наличие сертификата в этом хранилище для проверки подписи сценария.
  • Наконец, добавление самоподписанного сертификата в Центры сертификации доверенных корневых удостоверяющих центров гарантирует, что ваш компьютер доверяет сертификатам в хранилищах Личные и Доверенные издатели.

4. Для подтверждения наличия сертификата с темой ATA Authenticode в хранилищах сертификатов Личные, Корневые и Доверенные издатели выполните следующие команды в PowerShell.

# Подтвердите наличие самоподписанного сертификата Authenticode в хранилище сертификатов компьютера
 Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
# Подтвердите наличие самоподписанного сертификата Authenticode в корневом хранилище сертификатов компьютера
 Get-ChildItem Cert:\LocalMachine\Root | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
# Подтвердите наличие самоподписанного сертификата Authenticode в хранилище сертификатов Доверенных издателей компьютера
 Get-ChildItem Cert:\LocalMachine\TrustedPublisher | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}
Confirming the creation of the new self-signed certificate

5. Чтобы просмотреть сертификат в графическом интерфейсе, откройте инструмент “Снимок сертификатов” и найдите созданный вами сертификат в папке Сертификаты внутри хранилищ сертификатов Личные, Центры сертификации доверенных корневых удостоверяющих центров, и Доверенные издатели.

Viewing certificates in the Microsoft Management Console (MMC)

Как подписать сценарии PowerShell

Теперь, когда вы создали и установили свой сертификат кодирования, вы готовы использовать его для подписи вашего образца сценария PowerShell. Когда вам нужно подписывать сценарии, команда Set-AuthenticodeSignature – основная звезда.

Чтобы подписать сценарий PowerShell, выполните код ниже в PowerShell. Первая команда получает сертификат кодирования из личного хранилища сертификатов локальной машины. Вторая команда добавляет цифровую подпись в файл сценария PowerShell.

# Получить сертификат кодирования из хранилища сертификатов локального компьютера с именем *ATA Authenticode* и сохранить его в переменную $codeCertificate.
$codeCertificate = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=ATA Authenticode"}

# Подписать сценарий PowerShell
# ПАРАМЕТРЫ:
# FilePath - Указывает путь к файлу сценария PowerShell для подписи, например C:\ATA\myscript.ps1.
# Certificate - Указывает сертификат для использования при подписи сценария.
# TimeStampServer - Указывает доверенный сервер отметок времени, который добавляет отметку времени к цифровой подписи вашего сценария. Добавление отметки времени гарантирует, что ваш код не истечет при истечении срока действия сертификата подписи.
Set-AuthenticodeSignature -FilePath C:\ATA\myscript.ps1 -Certificate $codeCertificate -TimeStampServer *<http://timestamp.digicert.com>*

Наиболее доверенные поставщики сертификатов имеют сервер времени, и вы можете найти их на веб-сайтах поставщиков. Например, сервер времени DigiCert находится по адресу http://timestamp.digicert.com, а у Comodo – http://timestamp.comodoca.com.

После подписания скрипта вы должны увидеть аналогичный вывод на скриншоте ниже.

How to Sign PowerShell Scripts

Проверка цифровой подписи скрипта PowerShell

На данный момент вы подписали скрипт PowerShell с использованием самоподписанного сертификата, который вы создали. Но как вы узнаете, есть ли у скрипта цифровая подпись?

Открытие кода

Один из способов подтвердить цифровую подпись скрипта – открыть скрипт и просмотреть код в текстовом редакторе. Как показано в примере ниже, подписанный скрипт имеет блок подписи в конце кода. Блок подписи начинается с # SIG # Begin signature block и заканчивается # SIG # End signature block.

Viewing the digital signature in the script’s content

Удаление цифрового блока подписи из кода скрипта приведет к отмене подписи скрипта.

Открытие свойств файла скрипта

Еще один способ проверить цифровую подпись скрипта – открыть свойства файла скрипта в Проводнике Windows. Для этого:

  1. В Проводнике Windows перейдите в расположение сценария PowerShell. В этом примере сценарий находится в C:\ATA\myscript.ps1.
  2. Щелкните правой кнопкой мыши по сценарию и выберите Свойства.
  3. На вкладке Цифровые подписи окна свойств файла вы увидите цифровую подпись в разделе Список подписей.
Viewing the digital signature in the script’s file properties

Используя Get-AuthenticodeSignature

Вы удивлены тем, что вы также можете проверить подпись сценария внутри PowerShell? Вероятно, нет. Команда, которую можно вызвать для получения подписи файла, – Get-AuthenticodeSignature.

Чтобы получить цифровую подпись сценария, выполните следующую команду. Эта команда получает подпись файла C:\ATA\myscript.ps1. Команда Select-Object -Property * отображает все детали подписи.

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

После выполнения команды вы увидите аналогичный результат на скриншоте ниже. Как видите, свойство SignerCertificate показывает детали сертификата подписи. А свойство TimerStamperCertificate отображает сертификат сервера отметок времени.

Viewing the digital signature in PowerShell

Запуск подписанного сценария PowerShell

На этом этапе вы подписали сценарий PowerShell и подтвердили, что цифровая подпись присутствует. Но окончательное испытание того, что вы выполнили все шаги правильно, – выполнить сценарий и подтвердить, что он работает.

PowerShell имеет функцию безопасности, которая защищает пользователей от случайного запуска сценариев. Эта функция безопасности называется Политики выполнения. В зависимости от политики выполнения, PowerShell может предотвращать или разрешать запуск сценариев.

Чтобы узнать о различных политиках выполнения и их влиянии на выполнение сценариев, обратитесь к Политикам выполнения PowerShell: Понимание и управление.

Чтобы запустить подписанный сценарий PowerShell, выполните следующие действия.

Сначала измените политику выполнения на AllSigned, чтобы гарантировать, что могут запускаться только подписанные сценарии. Без выполнения этого шага нельзя точно проверить, работает ли ваш подписанный сценарий. Для этого вызовите cmdlet Set-ExecutionPolicy, выполнив указанную ниже команду в PowerShell от имени администратора.

Set-ExecutionPolicy AllSigned

Затем выполните подписанный сценарий PowerShell.

C:\ATA\myscript.ps1

Сценарий должен запуститься без ошибок или предупреждений, как показано в результате ниже.

Running the signed script without errors

Однако, если сценарий был неправильно подписан или вообще не был подписан, вы получите ошибку, аналогичную изображению ниже. В этом случае пересмотрите свои действия и попробуйте подписать сценарий снова.

Running a script with errors regarding the digital signature

Что если вы в конечном итоге обновите свой сценарий? Будет ли цифровая подпись все еще действительной? Ответ – нет. Любое изменение в подписанном сценарии сделает недействительной цифровую подпись сценария. Запуск измененного сценария завершится ошибкой.

Следуйте этим шагам, чтобы протестировать измененный подписанный сценарий.

1. Откройте подписанный myscript.ps1 сценарий в редакторе кода или текста.

2. Измените код, добавив символ, например, подчеркивание в этом примере. Не изменяйте ничего другого.

Editing the signed script

3. Сохраните сценарий после изменения кода.

4. Наконец, выполните измененный сценарий в PowerShell, запустив команду ниже.

C:\ATA\myscript.ps1

Поскольку вы изменили подписанный сценарий, выполнение сценария приведет к ошибке, показанной ниже. Вам нужно будет подписать сценарий снова, чтобы обновить и исправить его цифровую подпись.

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.

Вывод

В этой статье вы узнали, почему подписание сценариев PowerShell может быть необходимо в зависимости от политик выполнения. Вы также узнали, как отличить подписанный и неподписанный сценарии. Наконец, вы узнали, как подписывать сценарии PowerShell цифровым образом и как их тестировать и запускать.

Сейчас, когда вы знаете, как подписывать сценарии PowerShell, будете ли вы начинать подписывать сценарии перед их распространением или развертыванием?

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