Contents of this directory is archived and no longer updated.

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

  • Restricted – запрещено исполнять любые скрипты, возможна работа только в интерактивной консоли
  • AllSigned – все скрипты должны быть криптографически подписаны
  • RemoteSigned – только полученные из недоверенных источников (например, интернет) скрипты должны быть подписаны
  • Unrestricted – наименее безопасный уровень, допускается исполнение любых скриптов

В версии V2 (пока ещё CTP3) скрипты PowerShell приравняли к исполняемым файлам и эти файлы стали неотключаемо мониториться политикой Software Restriction Policies. Я об этом уже писал ранее: PowerShell V2 и Software Restriction Policies. Поначалу меня это сильно напрягало, но после пришёл к мнению, что это правильно. Неправильно только то, что мы этого не видим (ps1 расширение нигде не фигурирует). С этим бороться можно двумя методами – явно указывать пути, откуда разрешён запуск .ps1 файлов или подписать их все.

Если компьютеров в сети больше одного, то самое идеальное для решения задачи будет наличие домена Active Directory и, по возможности, Enterprise Certification Authity (CA). Наличие домена решит массу задач, как распространение политики SRP в пределах домена, распространение сертификата в пределах домена, контроль версии сертификата, которым подписаны скрипты.

Итак, для начала нам нужно получить сертификат, которым будут подписываться скрипты. В целях безопасности следует создать ограниченную учётную запись пользователя из под которой администратор (в большинстве случаев) будет подписывать скрипты. В книге PowerShell In Action для генерации сертификата предлагается использовать makecert.exe, который входит в состав Visual Studio SDK, но как мне кажется более правильным будет использование CA. В Windows Server CA для этих целей есть уже готовый шаблон, который называется Code Signing. Но принципиальной разницы нету, каким инструментом вы будете генерировать сертификат и я опишу процесс получения сертификата с использованием доменного CA.

Если CA у нас уже установлен, то открываем оснастку Certification Authority и переходим в раздел Certificate Templates. Нажимаем правой кнопкой и выбираем Manage. Откроется редактор шаблонов. Если у вас Enterprise или Datacenter редакции Windows Server, то вы можете создать свой настроенный шаблон. Но я не вижу в этом необходимости. На данном этапе нам необходимо разрешить ограниченному пользователю запрашивать сертификаты этого шаблона. Для этого в закладке Security шаблона Code Signing нужно разрешить чтение и запрос сертификата ограниченному пользователю. Когда эта процедура проделана, редактор шаблонов можно закрыть. После чего в оснастке Certification Authority снова нажать правой кнопкой на разделе Certificate Templates –> New –> Certificate Template to Issue и в списке выбрать шаблон Code Signing.

После чего нужно залогиниться этим пользователем, запустить оснастку Certificate Manager (Start –> Run… –> certmgr.msc) и выполнить запрос сертификата. В списке шаблонов должен быть и добавленный нами Code Signing. Когда сертификат будет запрошен не надо закрывать оснастку сертификатов. Далее нам потребуется экспортировать открытую часть сертификата в x509 файл (с расширением .cer). Экспорт открытой части нам потребуется для проверки подписи и организации доверия подписи в пределах домена. Экспортированный сертификат необходимо теперь доставить администратору(-ам), который отвечает за групповую политику.

В групповых политиках (чаще всего в доменной политике) необходимо создать новую политику Software Restriction Policies и в Additiona Rules добавить правило сертификата (Certificate Rule) и указать экспортированный сертификат. Это необходимо затем, что PowerShell для проверки доверия сертификата ищет его в контейнере Trusted Publishers и только Software Restriction Policies позволяет централизовано распространять сертификаты в этот контейнер.

Теперь можно приступать к подписыванию скриптов. Для этих целей используется командлет Set-AuthenticodeSignature и синтаксис его такой:

Set-AuthenticodeSignature $file $cert

Где $file – путь к скрипту и $cert – объект сертификата, который получается следующим образом:

$cert = @(dir cert:\CurrentUser\My -codesigning)[0]

здесь мы явно указываем, что нам нужен сертификат, у которого в EKU (Enchanced Key Usage) указан Code Sgining. В нашем случае он будет всего 1. Но если их окажется несколько, то мы выберем самый первый. Вот как это будет выглядеть на практике:

[Desktop] Set-ExecutionPolicy allsigned [Desktop] Get-ExecutionPolicy AllSigned [Desktop] .\uptime.ps1 File C:\Documents and Settings\Signer\Desktop\uptime.ps1 cannot be loaded. The file C:\Documents and Settings\Signer \Desktop\uptime.ps1 is not digitally signed. The script will not execute on the system. Please see "get-help about_signing" for more details.. At line:1 char:13 + .\uptime.ps1 < +="" categoryinfo="" :="" notspecified:="" (:)="" [],="" pssecurityexception="" +="" fullyqualifiederrorid="" :=""> [Desktop] $cert = @(dir cert:\currentuser\my -codesigning)[0] [Desktop] $cert Directory: Microsoft.PowerShell.Security\Certificate::currentuser\my Thumbprint Subject ---------- ------- 42E5B32A19885C6ADCF9683BDA1C871E0FE5E0DB CN=Signer, CN=Users, DC=contoso, DC=com [Desktop] Set-AuthenticodeSignature uptime.ps1 $cert Directory: C:\Documents and Settings\Signer\Desktop SignerCertificate Status Path ----------------- ------ ---- 42E5B32A19885C6ADCF9683BDA1C871E0FE5E0DB Valid uptime.ps1 [Desktop] .\uptime.ps1 System Uptime for DC1 is: 1 days 4 hours 19 minutes 20 seconds [Desktop]

Я наглядно показал, как это работает. Мы сначала перевели политику исполнения скриптов в AllSigned и убедились, что неподписанный скрипт не исполняется. После чего я подписал этот скрипт и попробовал снова. Как видите, скрипт теперь исполнился.

Если не будет выполнено условие распространения сертификата посредством политики SRP в контейнер Trusted Publishers, то вы получите вот такое сообщение:

[Desktop] .\uptime.ps1 Do you want to run software from this untrusted publisher? File C:\Documents and Settings\Signer\Desktop\uptime.ps1 is published by CN=Signer, CN=Users, DC=contoso, DC=com and is not trusted on your system. Only run scripts from trusted publishers. [V] Never run [D] Do not run [R] Run once [A] Always run [?] Help (default is "D"):d File C:\Documents and Settings\Signer\Desktop\uptime.ps1 cannot be loaded because you have elected to no t run this software now. At line:1 char:12 + .\uptime.ps1 [Desktop]

Вот таким образом мы решаем задачу исполнения только проверенного набора скриптов. В этом смысле PowerShell 1.0 менее безопасный и удобный, поскольку мы не можем политикой SRP блокировать исполнение PS1 файлов как класс и имеем только один выход – принудительное подписывание скриптов. В версии V2 политика исполнения скриптов удобно интегрируется с SRP. Удобство интегрирования в том, что SRP помимо распространения сертификата в пределах домена так же на основе этого правила разрешает исполнять эти скрипты в обход общего ограничения на PS1 файлы.

В следующем посте я расскажу, как можно упростить процесс подписывания скриптов. Так что не отключаемся :-)


Share this article:

Comments:

Comments are closed.