Одно из важных соображений, которые при выполнении сценариев Windows PowerShell следует принимать во внимание в контексте обеспечения безопасности, это необходимость предотвращать несанкционированный запуск сценариев на системе. По умолчанию выполнение сценариев в среде PowerShell не предусмотрено. Однако сценарии являются эффективным средством администрирования Windows, поэтому, если вы эксплуатируете оболочку PowerShell, вам, вероятнее всего, случается ими пользоваться.
Сценарий PowerShell — это обычный текстовый файл с расширением. ps1. Файл содержит одну или несколько инструкций PowerShell, которые выполняются при вызове сценарного файла с консоли. PowerShell дает пользователю возможность определять, допустимо ли выполнение сценариев, и если да — указывать, какие сценарии могут выполняться. Чтобы управлять выполнением сценариев и обеспечить более высокий уровень защиты системы, следует:
- сформировать политику выполнения PowerShell;
- создать сертификат X.509;
- удостоверять сценарии цифровой подписью.
.
Формирование политики выполнения
Политика выполнения PowerShell определяет, допустимо ли выполнение сценариев и будут ли загружаться файлы конфигурации при запуске оболочки PowerShell. Для формирования политики выполнения нужно воспользоваться составной командой Set-ExecutionPolicy и указать с ее помощью один из следующих параметров выполнения.
- Restricted: файлы конфигурации PowerShell не загружаются и сценарии не выполняются. Этот обеспечивающий самые жесткие ограничения параметр применяется по умолчанию. В результате после того, как вы установили PowerShell, непреднамеренное выполнение сценариев, а также загрузка данных конфигурации исключаются. В то же время вы можете выполнять отдельные команды с консоли PowerShell.
- AllSigned: все сценарии и файлы конфигурации должны быть удостоверены цифровой подписью пользующегося доверием издателя. Для подписи сценария вы должны задействовать сертификат подписи кода. Как будет показано ниже, такой сертификат можно создать самостоятельно.
- RemoteSigned: все сценарии и файлы конфигурации, загруженные из Интернета, должны быть удостоверены цифровой подписью. Однако сценарии, хранящиеся на вашем компьютере, могут выполняться, а локальные файлы конфигурации загружаться и в том случае, если они не имеют цифровой подписи.
- Unrestricted: выполняются все сценарии и загружаются все файлы конфигурации. Этот вариант связан с наименьшими ограничениями и, следовательно, сопряжен с наибольшим риском.
Таким образом, если вы хотите защитить систему, но в то же время обеспечить возможность выполнения сценариев и загрузки файлов конфигурации, следует определить политику выполнения как AllSigned. Для этого введите в окне командной строки PowerShell следующую команду:
Set-ExecutionPolicy AllSigned
Вы можете выяснить, какая политика выполнения PowerShell применяется в данный момент (что всегда полезно делать после изменения политики), выполнив команду Get-ExecutionPolicy (без каких-либо параметров). Для получения более подробных сведений о составных командах Set-ExecutionPolicy и Get-ExecutionPolicy обратитесь к файлам справочно-консультационной системы PowerShell. Сведения о файлах конфигурации (то есть о файлах профилей) можно найти в статье «Windows PowerShell Profiles», которая размещена в сети MSDN (http://msdn.microsoft.com/en-us/library/bb613488(VS.85).aspx).
Создание сертификата X.509
Если для политики выполнения указан параметр AllSigned, это значит, что вы должны подписывать свои файлы; иначе говоря, вам необходим сертификат подписи кода X.509. X.509 — криптографический стандарт, определяющий формат для таких связанных с обеспечением безопасности устройств, как сертификаты открытых ключей и списки отозванных сертификатов. Вы можете либо приобрести сертификат X.509, выпущенный общедоступным удостоверяющим центром, либо создать собственный удостоверяющий центр и сертификат. Полное описание стандарта X.509 и общедоступных центров сертификации не относится напрямую к теме данной статьи. Однако я объясню, как вы можете создать собственный локальный удостоверяющий центр и сертификат.
Чтобы создать удостоверяющий центр и сертификат на локальном компьютере, вы можете воспользоваться утилитой Makecert, входящей в состав комплекта Microsoft.NET Framework SDK. Кроме того, утилита прилагается к пакетам Microsoft Visual Studio 2008 и Visual Studio 2005. Отметим, впрочем, что программа Makecert предназначена только для целей тестирования. Для создания центров сертификации и сертификатов в производственной среде необходимо задействовать инфраструктуру открытых ключей, например Microsoft Certificate Services.
Как и всякую другую утилиту командной строки, программу Makecert можно выполнять в строке с приглашениями PowerShell. Например, когда вы создаете удостоверяющий центр (что необходимо сделать перед тем, как приступать к созданию сертификата), требуется указать имя утилиты (Makecert), а также необходимые параметры. В следующем примере я создаю удостоверяющий центр с именем PowerShell CA в корневом хранилище сертификатов:
makecert -n "CN=PowerShell CA" ` -eku 1.3.6.1.5.5.7.3.3-r ` -sv PowerShellCA.pvk PowerShellCA.cer ` -ss Root -a sha1
Эта команда включает ряд параметров. В приведенной таблице содержится их краткое описание.
Таблица. Параметры команды Makecert, использованные в примере |
Подробную информацию об этих, а также о других параметрах можно найти на сайте .NET Framework Development Center сети MSDN (http://msdn.microsoft.com/en-us/library/bfsktky3(VS.80).aspx). Следует отметить, что для запуска команды в приведенном примере я добавил к переменной среды Path system путь к каталогу, где размещается утилита Makecert.
При запуске данной команды открывается диалоговое окно Create Private Key Password (экран 1) с предложением ввести пароль.
Экран 1. Диалоговое окно Create Private Key Password |
После того как вы дважды введете пароль и нажмете кнопку ОК, на экране появится диалоговое окно Enter Private Key Password (экран 2) с предложением ввести пароль, который вы только что указали в диалоговом окне Create Private Key Password.
Экран 2. Диалоговое окно Enter Private Key Password |
Когда вы нажмете ОК, на экране появится окно сообщения Security Warning (подобное показанному на экране 3), содержащее предупреждение о том, что вы собираетесь установить удостоверяющий центр PowerShell CA.
Экран 3. Окно сообщения Security Warning |
Когда вы нажмете кнопку Yes, утилита Makecert создаст удостоверяющий центр в вашем локальном хранилище сертификатов.
Следующий после формирования центра сертификации шаг — создание с помощью утилиты Makecert фактического сертификата, пригодного для подписи сценариев. Ниже приводится команда для создания сертификата PowerShell Certificate, авторизованного удостоверяющим центром PowerShell CA:
makecert -n "CN=PowerShell Certificate" ` -eku 1.3.6.1.5.5.7.3.3-pe ` -iv PowerShellCA.pvk ` -ic PowerShellCA.cer -ss My -a sha1
Как и в случае с предыдущей командой, эта команда включает ряд параметров Makecert. Описания этих параметров тоже приводятся в таблице. Надо отметить, что параметру -ss (который определяет хранилище сертификатов) я задал значение My, а не значение Root, которое было использовано мною при создании центра сертификации. Значение My указывает на то, что сертификат будет размещен в хранилище сертификатов папки Personal хранилища Current User. Хранилище Current User используется по умолчанию. Вы также можете задействовать параметр -sr LocalMachine, чтобы поместить сертификат в хранилище сертификатов Local Computer.
Когда вы запускаете команду Makecert с целью создания сертификата, система опять предлагает ввести пароль. Речь идет о пароле закрытого ключа, который вы установили, создавая удостоверяющий центр. Затем создается сертификат в хранилище Trusted Root Certification Authorities текущего пользователя.
Просматривать сертификат можно в окне оснастки Certificates консоли Microsoft Management Console (MMC; см. экран 4).
Экран 4. Оснастка MMC Certificates |
Обратите внимание, что PowerShell Certificate отображается в правой панели окна MMC. Для просмотра деталей сертификата дважды щелкните на нем, чтобы открыть диалоговое окно Certificate. Если оснастка Certificates не представлена в существующем средстве управления, придется добавить ее к консоли MMC. Информацию о том, как это делается, можно найти в статье Microsoft «How To Create Custom MMC Snap-in Tools Using Microsoft Management Console» (http://support.microsoft.com/kb/230263). Удостоверившись в том, что сертификат действительно создан, вы сможете приступить к заверению своих сценариев.
Заверение сценариев PowerShell подписью
Заверение сценария подписью — процесс достаточно простой. Нужно взять составную команду Set-AuthenticodeSignature и указать подлежащий заверению сценарный файл, а также сертификат подписи кода, который будет использоваться для заверения файла. Например, вы хотите заверить сценарный файл C:\Audit\SecurityAudit.ps1, представленный во фрагменте A листинга. Этот сценарий выводит 20 последних событий, перечисленных в журнале безопасности.
Следующие инструкции сначала указывают сценарный файл и сертификат, а затем выполняют составную команду Set-AuthenticodeSignature:
$file = "C:\Audit\SecurityAudit.ps1" $cert = Get-ChildItem cert:\CurrentUser\My ` -CodeSigningCert Set-AuthenticodeSignature $file $cert
В первой инструкции я назначаю полное имя файла в виде строки переменной $file. Во второй инструкции я использую команду Get-ChildItem для считывания сертификата подписи кода из хранилища сертификатов и присваиваю его переменной $cert. Чтобы считать сертификат, я указываю в качестве маршрута cert:\CurrentUser\My. Префикс cert: — это накопитель, используемый для обращения к хранилищу сертификатов. Далее следует CurrentUser, указывающий на каталог внутри хранилища сертификатов. Параметр My указывает на сертификаты, находящиеся в папке Personal. При использовании составной команды Get-ChildItem для считывания сертификата необходимо также включать параметр-переключатель -CodeSigningCert для считывания только тех сертификатов, которые имеют санкцию на подпись кода.
Если хранилище сертификатов My содержит более одного сертификата подписи кода, переменная $cert будет содержать эти сертификаты; в подобном случае нужно будет указать желаемый сертификат при ссылке на переменную $cert. Один из способов это сделать состоит в том, чтобы добавить индекс объекта после имени переменной. К примеру, при вызове первого сертификата подписи кода нужно употребить ссылку $cert [0], при вызове второго сертификата — ссылку $cert [1] и т. д. Но если вы знаете, что имеется только один сертификат подписи кода, индексы в квадратных скобках включать не следует.
После присвоения значений переменным $file и $cert можно приступать к подписи кода. В третьей инструкции, приведенной в нашем примере, для подписи кода используется команда Set-AuthenticodeSignature. Обратите внимание, что в качестве двух аргументов команде передается имя файла ($file) и имя сертификата ($cert). Когда вы запускаете эту команду, сертификат используется для заверения файла цифровой подписью. Проверить, заверен ли файл, можно, просмотрев его содержимое. В конце файла вы увидите блок кода с комментариями; это и есть цифровая подпись. Во фрагменте B листинга показано, как может выглядеть эта подпись. После заверения файла сценарий можно запускать.
При запуске сценария, заверенного цифровой подписью, система предложит удостоверить безопасность его выполнения. Вы можете дать команду никогда не выполнять этот файл, не выполнять его на этот раз, выполнить однократно или выполнять всегда. Если вы дадите команду никогда не выполнять этот файл или всегда выполнять его, в дальнейшем при попытке запустить сценарий система не будет предлагать вам удостоверить безопасность. В остальных случаях при попытке запустить сценарий вы будете получать такое предложение.
Подпись сценария с использованием файла .pfx
Если для подписи файлов вы используете личный сертификат, не исключено, что вредоносная программа подпишет сценарий с его помощью, и будет выполнен нежелательный сценарий. Избежать этого и обеспечить вашу систему еще более надежной защитой можно, экспортировав сертификат подписи кода в файл .pfx, чтобы в дальнейшем использовать этот файл для подписи сценария.
Чтобы экспортировать сертификат, откройте оснастку Certificates и отыщите свой сертификат (экран 4). Правой кнопкой мыши щелкните на сертификате подписи кода и в раскрывшемся меню выделите пункт All Tasks, а затем — Export. В результате будет запущен мастер Certificate Export. Для осуществления экспорта файла следуйте инструкциям мастера. Не забудьте экспортировать закрытый ключ вместе с сертификатом и обеспечить надежную защиту. Можете также указать, следует ли включать в маршрут сертификации все сертификаты, удалить закрытый ключ и экспортировать расширенные свойства. Потребуется еще указать пароль и местонахождение файла. Для рассматриваемых примеров я сохранил файл в каталоге C:\Audit\PS_Cert.pfx. Завершив процедуру экспорта сертификата, обязательно удалите его из хранилища сертификатов и проследите за тем, чтобы файл .pfx находился в безопасном месте.
После выполнения инструкций мастера все будет готово к подписи файла. Как и прежде, первые две инструкции должны определять необходимые переменные — так, например, как в следующем фрагменте кода:
$file = "C:\Audit\\SecurityAudit.ps1" $cert = Get-PfxCertificate C:\Audit\ PS_Cert.pfx
В первой инструкции я присваиваю местоположение файла сценария переменной $file. Далее я использую команду Get-PfxCertificate для считывания файла .pfx и сохраняю его в переменной $cert.
Когда вы запустите вторую инструкцию, система предложит ввести пароль. Речь идет о том пароле, который вы указали, когда экспортировали сертификат в файл. Как и прежде, для подписи файла используйте команду Set-AuthenticodeSignature. При запуске команды укажите файлы сценария и .pfx, как в следующем примере:
Set-AuthenticodeSignature $file $cert
Вот и все, что можно сказать по поводу заверения файла цифровой подписью. Как видите, после того как сценарий создан и, возможно, экспортирован в файл. pfx, процедура заверения файлов не должна вызвать затруднений. Между тем это эффективный способ обеспечения безопасности системы. Любой администратор знает, что в данном вопросе нельзя перестараться, особенно когда дело касается защиты сценариев PowerShell.
Начало фрагмента A $events = Get-EventLog Security -Newest 20 | sort -Property EntryType, Index Foreach ($event in $events) { $event.Index.ToString() + « - « + $event.TimeGenerated + « - « + $event.EntryType Write-Host } Конец фрагмента A Начало фрагмента B # SIG # Begin signature block # MIID/gYJKoZIhvcNAQcCoIID7zCCA+sCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUfuB/MNI2X1L7Kdw/G0iGyxaW # bHigggIcMIICGDCCAYWgAwIBAgIQs7M2bbLob59IMgMEJ4KiDjAJBgUrDgMCHQUA # MBgxFjAUBgNVBAMTDVBvd2VyU2hlbGwgQ0EwHhcNMDgwNTE2MTYzMDU2WhcNMzkx # MjMxMjM1OTU5WjAhMR8wHQYDVQQDExZQb3dlclNoZWxsIENlcnRpZmljYXRlMIGf # MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb1zprG3GPB/8xmPAEy5LyxdYw+V4w # Z5B57LVaSqvemioQofhsPLZAisRxnKJnqu6QikeOONlnioJJAhE3aZBY7meRi87N # 5ALYtrv4RWsQ73U4qbQdcyE8f8we9O76wGOuYEhUJGDIiR1WwexXZFGbG7fk8zlM # efa1V+gnjJdVuQIDAQABo2IwYDATBgNVHSUEDDAKBggrBgEFBQcDAzBJBgNVHQEE # QjBAgBDhKU0QbIB3f6Y3aWwYebXioRowGDEWMBQGA1UEAxMNUG93ZXJTaGVsbCBD # QYIQByoWGo48PJtNANXyw/l7nDAJBgUrDgMCHQUAA4GBAIvPeuaJDCI5PTcOQ8Iv # Md+aJwg9IOlw8U9E1oUD6gRfGXowUYN9HxOWHJoWrKn8wYyPGShWyPsmUxvOpo39 # vQv/0vUkud9Q+bCRBk+lov/fyqrQ9xmJoFRAl4H/WCQ2GyuFH8kP7ZNj8laz9Aa1 # dMFrtVIVVTrOSb03TWKjZmxHMYIBTDCCAUgCAQEwLDAYMRYwFAYDVQQDEw1Qb3dl # clNoZWxsIENBAhCzszZtsuhvn0gyAwQngqIOMAkGBSsOAwIaBQCgeDAYBgorBgEE # AYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwG # CisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBQNBhAb # I8NF5HE5NfibISx6S0ODaTANBgkqhkiG9w0BAQEFAASBgJjaY7cGezbKsWhg2+jr # f6ORTRw38vVIfC4x7XoTnl8SK522tRisEMXet5gUJSGqjvC6+ftwuBhi2FTOst3h # J5TEYa5knzZRe75HaEESsfY9ruqQCdHmaopPyi7Ov9xq/BMGAoqh1NDqAeLQIXs5 # kRGlV8SX/UgKHnv2otcq3r0e # SIG # End signature block Конец фрагмента B
Роберт Шелдон (contact@rhsheldon.com) — технический консультант и автор книг по технологиям Microsoft Windows и базам данных