Безопасность PowerShell


131 4

Russian Pages 98

Report DMCA / Copyright

DOWNLOAD PDF FILE

Recommend Papers

Безопасность PowerShell

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

Безопасность PowerShell

Перевод: Пётр Окунев, https://vk.com/peter1st

Безопасность PowerShell Ограничение языковых возможностей, безопасное общение, отслеживание злоупотреблений • • • • •

Управляйте выполнением сценариев с помощью политики выполнения, подписи кода и ограниченного языкового режима. Безопасное удаленное взаимодействие PowerShell с помощью SSH и TLS Делегируйте административные задачи с помощью JEA Аудит и анализ действий PowerShell, шифрование журналов Улучшайте качество кода, следуя рекомендациям

1 PowerShell как инструмент взлома: предотвращение злоупотребления скриптами PowerShell — это мощный инструмент для системного администрирования, а также идеальное средство для хакеров. Из-за тесной интеграции в систему попытки просто заблокировать PowerShell создают ложное впечатление безопасности. Наилучшую защиту обеспечивают собственные механизмы PowerShell. PowerShell предлагает почти неограниченный доступ к ресурсам компьютера с Windows, а также может автоматизировать многочисленные приложения, такие как Exchange. Пользователи не ограничены множеством модулей и командлетов, но могут также интегрировать классы .NET, API-интерфейсы Windows и COM-объекты. Эти возможности особенно опасны в руках злоумышленников. Поскольку во многих версиях используется Windows Server, Microsoft избегает активировать какие-либо роли и функции на только что установленной машине, чтобы свести к минимуму поверхность атаки. В такой заблокированной системе пользователи должны явно добавлять все необходимые службы.

1.1 Слабая конфигурация PowerShell по умолчанию Однако с PowerShell полный набор функций доступен с самого начала на каждом ПК с Windows, если вы отложите «защиту» с помощью ограничительной политики выполнения. Однако не рекомендуется оставлять это состояние как есть. Опасаться нужно не только злонамеренных экспертов по PowerShell, которые могут использовать все возможности скрипта. На самом деле даже базовых знаний достаточно, чтобы проникнуть в систему с помощью различных хакерских инструментов.

1.2 Инструменты взлома для PowerShell Многие из них можно легко получить с открытым исходным кодом через Github. К ним относятся обширные коллекции скриптов и модулей PowerSploit, PowerShell Empire, Nishang или PowerUp. Вы можете предположить, что ваши компьютеры хорошо защищены антивирусными сканерами, которые обнаруживают и блокируют эти хакерские инструменты. Фактически, Защитник Windows, например, вмешивается после загрузки и помещает сценарии в карантин.

Защитник Windows предотвращает загрузку PowerSploit Однако, в отличие от бинарных файлов, скрипты можно довольно легко изменить, чтобы обмануть распознавание на основе подписи. Например, вы можете скопировать Invoke-Mimikatz из окна браузера и вставить его в редактор, такой как PowerShell_ISE, чтобы поэкспериментировать с кодом. В этом сообщении в блоге Кэрри Робертс показано, как перехитрить большинство антивирусных сканеров путем поиска и замены нескольких важных фрагментов кода. На данный момент обсуждаемый метод, возможно, уже не актуален, но некоторые эксперименты, вероятно, покажут, как антивирусные сканеры обнаруживают этот скрипт. В противном случае различные средства обхода AMSI могут помочь вам перегрузить Защитник Windows.

1.3 Общая блокировка PowerShell Чтобы предотвратить такие угрозы, многие компании пойдут на радикальные меры и вообще отключат PowerShell. В средах с централизованным управлением эффективным решением является занесение в черный список с помощью AppLocker или политик ограниченного использования программ. Если вы решили использовать ограничение программного обеспечения, вы создаете два новых хешправила и подключаете их к powershell.exe и powershell_ise.exe. В качестве уровня безопасности выберите Not allowed (Не разрешено). Если вы заблокируете программы на уровне пользователя, администраторы могут быть исключены.

Блокировка powershell.exe с помощью политик ограниченного использования программ Этот подход имеет два недостатка. Во-первых, это может стать препятствием для системного администрирования, поскольку PowerShell стал незаменимым инструментом для большинства администраторов. Например, сценарии входа PowerShell, которые выполняются в контексте безопасности пользователя, больше не будут работать.

1.4 Обход через альтернативные оболочки Однако более серьезной проблемой является то, что PowerShell включает в себя нечто большее, чем просто powershell.exe или powershell_ise.exe, и поэтому его нельзя навсегда заблокировать, запретив доступ к этим двум файлам. Скорее, это системный компонент (System.Management.Automation), который нельзя удалить и который может использоваться различными средами выполнения. Таким образом, злоумышленники могут получить доступ к PowerShell из любой из своих собственных программ. Поэтому неудивительно, что уже существуют оболочки, которые можно интегрировать в ваш собственный код или запускать напрямую. Среди них p0wnedShell или PowerOPS. Кроме того, многочисленные версии PowerShell 6 и 7 доступны для скачивания в формате ZIP, который можно легко распаковать в каталог и выполнить. Частые предварительные версии PowerShell 7 донимают администраторов, поскольку им всегда приходится создавать новые правила для охвата всех этих версий. И последнее, но не менее важное: еще один обходной путь — скомпилировать сценарии PowerShell в исполняемые файлы. Они также не зависят от powershell.exe.

1.5 Безопасная оболочка PowerShell со встроенными механизмами Вместо того, чтобы полностью отказаться от PowerShell без обеспечения реальной безопасности, имеет смысл использовать его функции безопасности. Они были улучшены в версии 5, поэтому вам следует обновить ПК до последней версии PowerShell. Также настоятельно рекомендуется удалить PowerShell 2.0, который по-прежнему предустановлен в качестве дополнительной функции и может быть удален в Windows 8.1 и Server 2012 или более поздней версии. В этой старой версии можно обойти все основные ограничения PowerShell.

PowerShell 2.0 — это дополнительная функция, начиная с Windows 8 и Server 2012, которая включена по умолчанию. Одним из ключевых механизмов безопасности Windows PowerShell является ограниченный языковой режим (Constrained), который отключает несколько опасных функций. Этот языковой режим особенно эффективен при использовании в сочетании с белым списком приложений. При запуске PowerShell на удаленных компьютерах Конфигурации сеансов и Администрирование достаточного количества могут эффективно ограничить область действия для пользователей.

Выбор разрешенных параметров командлета для JEA Помимо средств предотвращения злоупотребления PowerShell, существуют также функции для отслеживания подозрительных и нежелательных действий. Сюда входит запись всех выполненных команд в лог-файлы (транскрипция), а также более новая функция Deep Scriptblock Logging. Последний записывает все действия PowerShell в журнал событий. Эти записи могут быть зашифрованы с помощью защищенного ведения журнала событий и, таким образом, защищены от посторонних глаз. В целом PowerShell имеет ряд механизмов, которые значительно затрудняют злонамеренное использование.

Просмотрщик событий представляет только зашифрованные записи, он не может их расшифровать. Ли Холмс составил таблицу в Microsoft PowerShell-Teamblog, в которой сравниваются функции безопасности различных языков программирования и оболочек. Это показывает, что PowerShell предлагает больше возможностей для предотвращения нежелательного использования, чем другие. Конечно, это не обеспечивает полной безопасности, ведь находчивые умы всегда найдут способы обойти защиту.

(Продолжение ниже)

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

2 Ограничить выполнение скриптов 2.1 Настройка политики выполнения Выполнение скриптов PowerShell может быть ограничено политиками, по умолчанию оно заблокировано. В то время как политика выполнения, установленная администратором в интерактивном режиме, может быть переопределена любым пользователем, настройка через GPO более устойчива. Однако он по-прежнему не обеспечивает защиту от злоумышленников. Основная цель политики выполнения — защитить пользователей от случайного запуска ненадежных скриптов. Параметр по умолчанию для только что установленной Windows — «Ограничено», поэтому ни один пользователь не может запускать сценарии PowerShell, даже администратор.

2.1.1 Настройки политики выполнения Другие возможные значения:  AllSigned: выполняются только подписанные сценарии от доверенного издателя, это также относится к сценариям, созданным локально.  RemoteSigned: Сценарии, загруженные из Интернета, должны быть подписаны доверенным издателем.  Unrestricted: выполняются все сценарии. Для неподписанных скриптов из Интернета необходимо подтверждать каждое выполнение по запросу.  Bypass: без ограничений, предупреждений или подсказок.  Undefined: удаляет назначенную политику.

2.1.2 Неявная область действия LocalMachine Например, если вы хотите изменить Restricted по умолчанию на RemoteSigned и введите команду Set-ExecutionPolicy RemoteSigned тогда произойдет сбой, если вы не открыли сеанс PowerShell с правами администратора.

Пользователи без прав администратора не могут изменить политику выполнения для области LocalMachine. Причина этого кроется в области действия политики выполнения. Если область не указана явно, SetExecutionPolicy предполагает LocalMachine. Это изменит настройки для всех пользователей на этом компьютере, поэтому для этого вам потребуются права администратора.

2.1.3 Перезапись настроек для всего ПК для пользователя Как известно из программирования, конкретная область действия переопределяет более общую. Если вы определяете политику выполнения для текущего пользователя, она перезаписывает политику для локальной машины. Таким образом, любой пользователь может переопределить ограничительный общесистемный параметр следующим образом: Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

Область действия Process, влияющая на текущий сеанс, еще более специфична. Параметр для этого хранится не в реестре, как обычно, а в переменной среды $env:PSExecutionPolicyPreference. Он сбрасывается в конце сеанса.

2.1.4 Отображение политик для всех областей Конфигурацию политики выполнения для каждой области можно отобразить с помощью:

Get-ExecutionPolicy -List | ft -AutoSize Область действия PowerShell ExecutionPolicy В дополнение к областям LocalMachine, CurrentUser и Process, описанным выше, в выходных данных командлета появляются две другие, а именно MachinePolicy и UserPolicy. Значения для них можно установить только с помощью групповой политики.

2.1.5 Определение политики выполнения через GPO Параметр, отвечающий за настройку политики выполнения, можно найти для конфигурации компьютера и пользователя в разделе Policies => Administrative Templates => Windows Components => Windows PowerShell и назван Turn on Script Execution.

Параметр GPO для настройки политики выполнения PowerShell. Настроенная таким образом политика выполнения переопределяет интерактивно определенные значения, а также не позволяет администратору изменять их в командной строке. Обход путем вызова новой оболочки с powershell.exe -ExecutionPolicy "Unrestricted" также не работает, тогда как этот метод можно использовать для переопределения политики для LocalMachine. Кроме того, сброс на значение Undefined возможен только путем деактивации объекта групповой политики. Таким образом, можно использовать групповую политику, чтобы указать, каким критериям должны соответствовать сценарии, чтобы их можно было запускать (кстати, эта политика не влияет на сценарии входа в систему). Это предотвращает случайное повреждение ненадежными сценариями из-за слишком нестрогих настроек.

2.1.6 Нет защиты от злоумышленников Если пользователь решит обойти эту политику, он просто скопирует содержимое скрипта в ISE и запустит его там. RemoteSigned позволяет запускать неподписанные скрипты, загруженные из Интернета, если вы разблокируете файл с помощью Unblock-File. Другой способ обхода заключается в кодировании скрипта в Base64 и передаче его в PowerShell.exe через параметр EncodedCommand. Чтобы ограничить возможный ущерб, причиняемый такими действиями, рекомендуется использовать ограниченный языковой режим.

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

2.2.1 Ограничение через политику выполнения, CLM, AppLocker Одним из механизмов отклонения неподписанных сценариев является политика выполнения. Если установлено значение AllSigned, должны быть подписаны как локальные сценарии, так и сценарии, загруженные из Интернета. Но эта мера не является надежной, поскольку пользователи могут скопировать содержимое сценария в приглашение или в ISE и запустить его там. Ограниченный языковой режим (CLM) обеспечивает большую защиту, поскольку он позволяет только подписанным сценариям использовать все функции PowerShell. С другой стороны, неподписанным сценариям будет отказано в доступе к функциям, имеющим очень разрушительный потенциал. Наконец, решения для внесения приложений в белый список имеют самый сильный эффект в блокировании ненадежных скриптов. Например, AppLocker можно использовать для ограничения выполнения сценариев от определенных поставщиков.

2.2.2 Назначение разрешений шаблону сертификата Первый шаг — убедиться, что шаблон сертификата для подписи кода доступен пользователям, которые хотят запросить сертификат для своих скриптов. Для этого откройте Центр сертификации инструмента на основе MMC (certsrv.msc) и подключитесь к внутреннему ЦС.

Откройте шаблоны сертификатов из Центра сертификации инструмента MMC (certsrv.msc).

В контекстном меню шаблонов сертификатов выполните команду Manage. Откроется оснастка для шаблонов сертификатов.

Назначение прав на шаблон для подписи кода Там вы выбираете «Properties» в контекстном меню «Code signing» и переключаетесь на вкладку «Security». Затем вы добавляете группу, которая должна запрашивать сертификаты на основе этого шаблона, и предоставляете ей разрешения на чтение и регистрацию.

Открытие диалогового окна активации шаблонов сертификатов После подтверждения этого диалога вернитесь к certsrv.msc. В контекстном меню шаблонов сертификатов выполните команду New => Certificate Template to Issue. В следующем диалоговом окне вы выбираете подпись кода и закрываете ее, нажав Ok.

Включение шаблона сертификата для подписи кода

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

Запросить новый сертификат подписи кода Здесь вы щелкаете правой кнопкой мыши на Personal и затем выбираете All Tasks => Request New Certificate. При этом запускается мастер, в котором вы выбираете политику регистрации сертификатов в первом диалоговом окне (обычно это политика по умолчанию для AD). Затем вы выбираете шаблон Code Signing, открываете его детали и нажимаете «Свойства». В появившемся диалоговом окне введите необходимые данные в разделе «Тема» и перейдите на вкладку «Закрытый ключ», чтобы установить флажок «Сделать закрытый ключ экспортируемым».

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

Успешное завершение запроса сертификата

2.2.4 Подписание скрипта Сертификат теперь можно найти в локальном хранилище пользователя в Personal => Certificates. Это можно отобразить в PowerShell с помощью соответствующего провайдера: Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert Вы можете воспользоваться этой командой, используемой для указания сертификата при подписании скрипта с помощью Set-AuthenticodeSignature: Set-AuthenticodeSignature myScript.ps1 ` (dir Cert:\CurrentUser\My -CodeSigningCert)

Подписание скрипта с помощью командлета Set-AuthenticodeSignature PowerShell вставит подпись в формате Base64 в виде отдельного блока в конце скрипта.

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

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

2.2.5 Пометка подписи отметкой времени После подписания скрипта PowerShell откажется его выполнять, если вы внесете в него хоть малейшее изменение. Единственное средство — переподписать сценарий. То же самое происходит, когда срок действия сертификата истекает. В этом случае сценарий также нельзя использовать. Но вы можете предотвратить это, используя сервер меток времени при подписании.

Подпись с отметкой времени В этом примере используется бесплатный сервис Globalsign: Set-AuthenticodeSignature myScript.ps1 ` (gci Cert:\CurrentUser\My -CodeSigningCert)` -TimestampServer http://timestamp.globalsign.com/scripts/timstamp.dll ` -HashAlgorithm "SHA256" Это доказывает, что сертификат был действителен на момент подписания.

2.3 Снижение рисков PowerShell с помощью ограниченного языкового режима PowerShell — это мощный инструмент, который может управлять практически всеми компонентами Windows и такими приложениями, как Exchange. Поэтому он может нанести большой ущерб в руках злоумышленников. Ограниченный языковой режим блокирует опасные функции и, таким образом, предотвращает их неправильное использование. По умолчанию PowerShell работает в полноязыковом режиме, в котором доступны все функции. Это включает доступ ко всем языковым элементам, командлетам и модулям, а также к файловой системе и сети.

2.3.1 Заблокированные функции Возможность создавать объекты COM и .NET или генерировать новые типы данных (с надстройкой), которые были определены на других языках, является особенно опасной способностью PowerShell.

Ограниченный языковой режим блокирует эти функции (кроме доступа к разрешенным классам .NET). Это также предотвращает объявление классов, использование управления конфигурацией с помощью DSC и рабочих процессов на основе XAML (полный список см. в Microsoft Docs).

2.3.2 Включение ограниченного языкового режима Простой способ переключиться в ограниченный языковой режим — установить ответственную переменную в желаемое значение: $ExecutionContext.SessionState.LanguageMode = ` "ConstrainedLanguage"

Отображение и изменение языкового режима через переменную $ExecutionContext.SessionState.LanguageMode Очевидно, что установка этой переменной не дает никакой реальной защиты. Возможно, вы не сможете изменить его обратно на FullLanguage в том же сеансе, но новый сеанс PowerShell снова предложит полный набор языковых функций.

2.3.3 Переключение в ограниченный режим с помощью переменной среды Менее легко обойти (недокументированную) переменную системной среды __PSLockDownPolicy, если вы установите для нее значение 4. В результате PowerShell, независимо от того, является ли это просто командной строкой или ISE, будет запускаться в ограниченном режиме.

Установка переменной среды __PSLockDownPolicy в интерактивном режиме В средах с централизованным управлением вы, вероятно, зададите системную переменную, используя настройки групповых политик.

Установка переменной окружения __PSLockDownPolicy через GPO Недостатком этой процедуры является то, что она всегда затрагивает всех пользователей компьютера, включая администраторов. Однако администраторы могут временно удалить переменную среды, пока объект групповой политики снова не вступит в силу. Но это довольно громоздко и определенно не очень хорошее решение. Кроме того, при таком использовании это не функция безопасности, поддерживаемая Microsoft, и ее относительно легко обойти. Тем не менее, это может помешать большинству оппортунистических атак. Таким образом, строгое соблюдение ограниченного языкового режима на локальном компьютере требует использования ограничения выполнения программного обеспечения, такого как AppLocker или Application Control в Защитнике Windows. Однако в удаленном сеансе это можно сделать с помощью конфигурации сеанса.

2.3.4 Автоматическое определение ограничения выполнения Начиная с версии 5, на основе правил сценариев PowerShell автоматически распознает, следует ли ей переключиться в языковой режим с ограничениями. Для этого он создает модуль и сценарий (с именем, соответствующим шаблону __PSSCRIPTPOLICYTEST_LQU1DAME.3DD.PS1) в $env:temp и пытается их выполнить. Если AppLocker или другой инструмент заблокирует эту попытку, PowerShell запустится в ограниченном языковом режиме.

Журнал событий показывает, было ли выполнение тестовых сценариев успешным или нет. Эффект этого механизма можно легко увидеть в журнале событий AppLocker. AppLocker регистрирует создание и выполнение этих тестовых файлов с идентификатором 8005 (успех) или 8007 (выполнение заблокировано) в разделе Services Log => Microsoft => Windows => AppLocker => MSI and Script.

2.3.5 Настройка AppLocker Если вы используете AppLocker для этой задачи, вам необходимо создать новый объект групповой политики, а затем отредактировать его в редакторе объекта групповой политики. Там вы переходите в Computer Configuration => Policies => Windows Settings => Security Settings => Application Control Policies => AppLocker и переходите по ссылке «Настроить применение правил». В появившемся диалоговом окне вы активируете опцию Правила сценария.

Включение применения правил для скриптов в AppLocker Чтобы AppLocker блокировал приложения в целевых системах, должна быть запущена служба Application Identity. Он не активен по умолчанию и не запускается при загрузке системы. Вы можете изменить его на тип запуска «Автоматически» либо в интерактивном режиме, используя службы оснастки MMC, либо из командной строки: sc config AppIDSvc start=auto

Установка типа запуска для службы идентификации приложений на автоматический Для централизованного управления этой службой Windows рекомендуется использовать групповую политику.

2.3.6 Определение правил Наконец, необходимо определить правила, которые блокируют запуск скриптов в каталоге Temp. Для этого просто переключитесь на «Правила сценариев» под AppLocker и выберите «Создать правила по умолчанию» в контекстном меню.

Создание правил по умолчанию для скриптов в AppLocker Они позволяют обычным пользователям выполнять сценарии только из каталогов Windows или Program Files, то есть в местах, где пользователи не могут сами хранить какие-либо файлы. Администраторы явно освобождены от этого ограничения отдельным правилом.

2.3.7 Активация ограниченного языкового режима через SRP AppLocker — это эксклюзивная функция выпусков Enterprise и Education. Поэтому версия Pro может вместо этого использовать политики ограниченного использования программ (SRP). Опять же, вам просто нужно убедиться, что два тестовых сценария не могут быть выполнены в каталоге %temp%. Для этого создайте объект групповой политики, откройте его в редакторе и перейдите к Computer Configuration => Policies => Windows Settings => Security Settings => Software Restriction Policies.

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

Создание нового правила пути для ограничения программного обеспечения Затем вы создаете новое правило пути в разделе «Дополнительные правила». Здесь вы вводите %temp% в качестве пути и оставляете для параметра «Уровень безопасности» значение «Запрещено».

Определение правила пути для каталога Temp

2.3.8 Предотвращение обхода PowerShell 2.0 Независимо от того, выберете ли вы переменную среды, AppLocker или политики ограниченного использования программ, вам потребуется удалить PowerShell 2.0 с компьютеров, на которых вы хотите применить ограниченный языковой режим.

PowerShell 2.0 — это дополнительная функция, начиная с Windows 8 и Server 2012, которая включена по умолчанию. Он был представлен только в PowerShell 3.0, и хакер может легко обойти его, переключившись на более старую версию. Все, что ему нужно сделать, это ввести команду: powershell.exe -version 2.0 Вы можете проверить, активирована ли эта старая версия на ПК, введя: Get-WindowsOptionalFeature -Online ` -FeatureName MicrosoftWindowsPowerShellV2 Однако вы можете удалить его только в Windows 8 и Server 2012 или более поздних версиях, где PowerShell 2.0 является дополнительной функцией.

3 Безопасная связь 3.1 Установка OpenSSH в Windows 10 и Server 2019 Windows Server 2019 впервые включает OpenSSH в качестве дополнительной функции, что упрощает установку и настройку. Однако ошибки в более ранних сборках операционной системы препятствуют успешной активации SSH-сервера. В средах WSUS OpenSSH имеет те же проблемы, что и RSAT. Перенос OpenSSH на Windows упрощает управление разнородными средами. Компьютеры Linux можно удаленно администрировать через SSH из Windows, а благодаря новому серверу OpenSSH теперь

возможно и обратное. Кроме того, PowerShell Core поддерживает удаленное взаимодействие через SSH даже между разными ОС.

3.1.1 Сервер OpenSSH, не включенный в операционную систему Можно было бы ожидать, что системный компонент с такой стратегической важностью поставляется как часть операционной системы и может быть установлен как функция через диспетчер серверов или PowerShell. Однако Microsoft решила предоставить OpenSSH в качестве дополнительной функции (также называемой «Функция по запросу»). Это объединяет установку клиентской и серверной ОС. Поэтому следующее описание также относится к Windows 10, начиная с версии 1803.

3.1.2 Установка через графический интерфейс Чтобы установить сервер OpenSSH, запустите Apps => Apps and Features => Manage Optional Features. Как видно из списка установленных компонентов, клиент SSH уже установлен по умолчанию. С другой стороны, сервер необходимо добавить с помощью параметра «Добавить функции».

Установка сервера OpenSSH через приложение настроек В списке выше выберите сервер OpenSSH и нажмите появившуюся кнопку «Установить». Теперь Windows загрузит необходимые файлы через Интернет. Если произойдет ошибка, вы не получите сообщение от приложения «Настройки», а просто вернетесь к списку функций.

3.1.3 Добавление OpenSSH-сервера через PowerShell Напротив, PowerShell обеспечивает большую прозрачность. Чтобы узнать точное имя требуемого пакета, введите следующую команду: Get-WindowsCapability -Online | ? name -like *OpenSSH.Server* Наконец, вы добавляете отображаемое имя в Add-WindowsCapability.

Добавление сервера OpenSSH через PowerShell Кроме того, вы можете передать вывод через конвейер: Get-WindowsCapability -Online | where name -like *OpenSSH.Server* | AddWindowsCapability -Online

3.1.4 Ошибочные сборки Есть как минимум две причины, по которым вы можете столкнуться с проблемами здесь. Если сборка системы старше 17763.194, то вы увидите ошибку: Add-WindowsCapability failed. Error code = 0x800f0950

Установка OpenSSH Server завершается сбоем в более ранних сборках Windows Server 2019.

В этом случае вам понадобится актуальное накопительное обновление для решения проблемы.

3.1.5 Проблемы с WSUS Еще одно препятствие возникает, если сервер, как это обычно и бывает, обновляется через WSUS. Microsoft предоставляет функции по запросу, минуя WSUS, поэтому вы не получаете их через внутренний сервер обновлений. Поэтому вполне вероятно, что PowerShell выдаст здесь следующую ошибку: Error with "Add-WindowsCapability". Error code: 0x8024002e

Ошибка при установке OpenSSH в качестве дополнительной функции в средах WSUS. В журнале событий вы найдете запись с идентификатором 1001, в которой говорится, что пакет OpenSSH-Server-Package недоступен.

Запись журнала событий при добавлении сервера OpenSSH в качестве дополнительного компонента в среду WSUS

Как и в случае с RSAT, решение состоит в том, чтобы позволить Windows загружать дополнительные функции непосредственно из Центра обновления Майкрософт с помощью групповой политики. Параметр называется Specify settings for optional component installation and component repair и находится в разделе Computer Configuration => Policies => Administrative Templates => System.

Разрешение клиентам WSUS получать доступ к Центру обновления Windows с помощью групповой политики. В то же время необходимо убедиться, что ни параметр Do not connect to Windows Update Internet locations, ни Remove access to use all Windows Update features не действуют. Последнее могло быть включено, чтобы пользователи не могли вручную загружать обновления функций. В первую очередь это влияет на Windows 10, а не на сервер.

3.1.6 Активация SSH-сервера OpenSSH Server устанавливает две службы, которые еще не запущены и тип запуска которых — ручной и отключен. Если вы хотите регулярно использовать SSH, вам нужно будет запускать службы автоматически.

Отображение типа запуска и состояния служб SSH с помощью PowerShell

Это можно настроить с помощью сервисов графического интерфейса, но самый быстрый способ — использовать PowerShell: Set-Service sshd -StartupType Automatic Set-Service ssh-agent -StartupType Automatic Чтобы немедленно запустить SSH-сервер, необходимо также запустить две службы вручную: Start-Service sshd Start-Service ssh-agent Эта команда: Get-Service -Name *ssh* | select DisplayName, Status, StartType используется для проверки совпадения настроек двух служб и их успешного запуска. Теперь вы можете проверить, правильно ли активировано правило брандмауэра для входящих SSH-соединений: Get-NetFirewallRule -Name *SSH*

Проверка правила брандмауэра для SSH

3.1.7 Проверка соединения Если это условие также выполнено, то тест соединения можно начинать. С ПК с Windows 10 или компьютера с Linux вы можете подключиться к свеженастроенному серверу: ssh Это направит вас к старой командной строке, но вы также можете запустить PowerShell там.

Установите соединение со свежеустановленным SSH-сервером

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

3.2 Удаленное взаимодействие PowerShell с аутентификацией по открытому ключу SSH Одно из преимуществ удаленного взаимодействия PowerShell через SSH по сравнению с удаленным взаимодействием на основе WinRM заключается в том, что вы можете работать с проверкой подлинности с открытым ключом. Это делает удаленное управление компьютерами Windows, которые не являются членами домена Active Directory, удобным и безопасным. Если вы работаете с WinRM в среде без Active Directory, все становится довольно запутанным и неудобным, если для вас важна безопасность. Вы должны переключиться с протокола HTTP по умолчанию на протокол HTTPS, иметь дело с сертификатами SSL/TLS и с доверенными хостами. Удаленное взаимодействие через SSH, представленное в PowerShell 6, не требует проверки подлинности с открытым ключом. Вместо этого также принимаются имя пользователя и пароль. Основным недостатком является то, что вам придется вводить пароль Windows каждый раз, когда вы подключаетесь к удаленному компьютеру. Это может быть нормально для интерактивных сеансов с помощью Enter-PSsession, но если вы хотите запускать свои сценарии удаленно с помощью InvokeCommand, это может стать проблемой. Кроме того, аутентификация с открытым ключом повышает безопасность, поскольку она удобно работает без использования паролей. Таким образом, имеет смысл потратить немного больше времени и настроить удаленное взаимодействие PowerShell для аутентификации с открытым ключом.

3.2.1 Локальная конфигурация Первое, что вам нужно сделать, это создать закрытый и открытый ключи, что вы можете сделать, просто запустив команду ssh-keygen. По умолчанию, команда сохраняет пару ключей в папке .ssh в вашем профиле пользователя. id_rsa — закрытый ключ, а id_rsa.pub — открытый ключ. Если вы хотите работать без кодовой фразы, вы можете просто дважды нажать Enter. Тем не менее, я рекомендую использовать кодовую фразу, потому что, если кто-то получит доступ к вашему закрытому ключу, это скомпрометирует все ваши удаленные компьютеры. Благодаря ssh-агенту вам не нужно вводить парольную фразу всякий раз, когда вы подключаетесь к удаленному компьютеру. SSH-агент работает как служба и надежно хранит ваш закрытый ключ. В консоли PowerShell вы можете запустить ssh-агент следующим образом: Start-Service ssh-agent Если вы хотите, чтобы служба запускалась автоматически после перезагрузки, вы можете использовать эту команду: Set-Service ssh-agent -StartupType Automatic Чтобы добавить свой закрытый ключ в ssh-агент, вы должны ввести эту команду: ssh-add Вам нужно будет ввести пароль здесь один раз. После этого вы можете повторно переместить свой закрытый ключ из папки .ssh и сохранить его в более безопасном месте.

Создание пары ключей, добавление закрытого ключа к агенту ssh и повторное его удаление Если вы позже захотите удалить закрытый ключ из ssh-agent, вы можете сделать это с помощью этой команды: ssh-add -d ida_rsa Обратите внимание, что для этого требуется предоставить ключ SSH. Если вы потеряли свой закрытый ключ, вы можете удалить все закрытые ключи из ssh-агента: ssh-add -D

3.2.2 Удаленная конфигурация Далее вам нужно скопировать содержимое файла открытого ключа id_rsa.pub на удаленный хост. Просто вставьте его в файл author_keys в C:\Users\\.ssh\.

Открытый ключ для SSH (содержимое id_rsa.pub) По умолчанию аутентификация с открытым ключом включена в OpenSSH. Однако я рекомендую отключить аутентификацию по паролю из соображений безопасности. Если злоумышленник узнает ваш пароль Windows, он сможет подключиться к удаленному хосту даже без вашего закрытого ключа и парольной фразы.

Отключение аутентификации по паролю для SSH Чтобы отключить аутентификацию по паролю, запустите Блокнот с правами администратора, а затем откройте sshd_config в C:\ProgramData\ssh\. Добавьте "PasswordAuthentication no" в файл и сохраните его. Вы должны перезапустить службу ssh, чтобы применить изменения. Вы можете сделать это в консоли PowerShell с правами администратора: Restart-Service sshd

3.2.3 Подключение с аутентификацией по открытому ключу Теперь вы вернулись на свой локальный хост и готовы проверить соединение. В консоли PowerShell 6 или 7 просто введите следующую команду: Enter-PSession -HostName ` -UserName Параметр HostName гарантирует, что PowerShell будет подключаться через SSH вместо WinRM. Обратите внимание, что ваше имя пользователя на удаленном компьютере не обязательно должно совпадать, если вы используете параметр UserName. Если вы опустите этот параметр, PowerShell примет ваше текущее имя для входа на локальном компьютере. Обратите внимание, что вам не нужно вводить ни пароль Windows, ни парольную фразу для закрытого ключа. Invoke-Command работает точно так же: Invoke-Command -HostName ` -UserName ` -ScriptBlock {get-process}

Удаленное взаимодействие PowerShell через транспорт SSH и аутентификацию с открытым ключом Вы также можете подключиться к любому SSH-клиенту. OpenSSH поставляется с простым клиентом SSH, который можно запустить из командной строки: ssh @ Просто для полноты картины: если вы не сохранили свой закрытый ключ в ssh-агенте, вы все равно можете работать с аутентификацией с открытым ключом. Если закрытый ключ находится в папке .ssh вашего профиля пользователя, OpenSSH автоматически найдет ключ. Если вы сохранили ключ в другом месте, вы должны передать закрытый ключ. С клиентом ssh вы можете использовать параметр -i: ssh -i id_rsa @ Enter-PSsession и Invoke-Command имеют для этой цели параметр -IdentityFilePath: Enter-PSession -HostName ` -UserName ` -IdentityFilePath id_rsa Как упоминалось выше, я не рекомендую работать таким образом, потому что он требует хранения вашего закрытого ключа в виде открытого текста на вашем локальном компьютере. Даже если вы используете кодовую фразу, работать с ssh-agent более безопасно, потому что вы защищены от клавиатурных шпионов и других методов кражи паролей.

3.3 Создание самозаверяющего сертификата В то время как в Windows XP для выдачи самозаверяющих сертификатов требовались такие инструменты, как makecert.exe, в Windows 8 и Server 2012 PowerShell может взять на себя эту задачу с помощью своего командлета New-SelfSignedCertificate. Сертификаты можно использовать для аутентификации клиента и сервера или для подписи кода. Самозаверяющие сертификаты обычно используются в лабораториях или других небольших средах, где вы не хотите настраивать домен Windows или независимый центр сертификации. В этом случае эмитент и пользователь обычно являются одним и тем же лицом или принадлежат к небольшой группе.

3.3.1 Создание сертификата со значениями по умолчанию Для выдачи SSL-сертификата командлету New-SelfSignedCertificate требуется всего несколько параметров. Базовая команда в сеансе администрирования может выглядеть следующим образом: New-SelfSignedCertificate -DnsName lab.contoso.de ` -CertStoreLocation Cert:\LocalMachine\My

Создание самоподписанного SSL-сертификата с New-SelfSignedCertificate на основе настроек по умолчанию. Эта команда создает новый сертификат в разделе My в хранилище для локального компьютера с субъектом, заданным как «lab.contoso.de». С помощью команды dir Cert:\LocalMachine\my\ | fl -Property * вы можете видеть, что новый сертификат имеет, среди прочего, следующие свойства по умолчанию:  EnhancedKeyUsageList: {client authentication(1.3.6.1.5.5.7.3.2), server authentication (1.3.6.1.5.5.7.3.1)}  NotAfter: 22.03.2020 18:52:22  HasPrivateKey: True  Issuer: CN=lab.contoso.de  Subject: CN=lab.contoso.de

Если сертификат сгенерирован со значениями по умолчанию, он подойдет для аутентификации клиента и сервера. Без указания типа в вызове New-SelfSignedCertificate сертификат подходит для проверки подлинности клиента и сервера. Кроме того, он действителен в течение 1 года и имеет закрытый ключ, который также можно экспортировать, как показано certutil.

Отображение свойств нового сертификата в оснастке сертификата MMC. Командлет выдает сертификат SAN при использовании параметра DnsName. Там вы указываете альтернативные имена субъекта в виде списка, разделенного запятыми. Первый из них также служит субъектом, а также издателем, если вы не используете сертификат для подписи нового сертификата с помощью параметра подписывающего. Вы также можете указать подстановочные знаки, следуя шаблону New-SelfSignedCertificate -DnsName ` lab.contoso.de, *.contoso.de -cert Cert:\LocalMachine\My для создания подстановочных сертификатов.

3.3.2 Расширенные параметры в Windows 10 и Server 2016 Вы можете переопределить большинство значений по умолчанию для новых сертификатов своими собственными параметрами для New-SelfSignedCertificate, но только начиная с Windows 10 и Server 2016. До этого командлет принимал только параметры DnsName, CloneCert и CertStoreLocation. Следующая команда позволяет продлить срок действия за пределы одного года, указав дату: New-SelfSignedCertificate -DnsName lab.contoso.de ` -CertStoreLocation Cert:\LocalMachine\My ` -NotAfter (Get-Date).AddYears(2) В этом примере срок действия устанавливается равным 2 годам. Для сертификата также могут быть определены другие варианты использования, помимо проверки подлинности клиента и сервера. В дополнение к значению по умолчанию SSLServerAuthentication параметр Type также принимает следующие значения:  CodeSigningCert

 DocumentEncryptionCert  DocumentEncryptionCertLegacyCsp Кроме того, есть Custom, который активирует все функции сертификата. Их можно снова отменить по отдельности позже с помощью оснастки сертификата MMC.

Если вы выберете «Пользовательский» в качестве типа, вы создадите сертификат для всех целей. Если вы не хотите, чтобы закрытый ключ можно было экспортировать, вы можете добиться этого с помощью параметра: -KeyExportPolicy NonExportable

3.3.3 Экспорт сертификата Если вы хотите экспортировать сертификат в файл PFX, чтобы использовать его на веб-сервере IIS, для этой цели служит Export-PfxCertificate. Однако для этого требуется, чтобы целевой файл был защищен либо паролем, либо правами доступа, которые вы установили с помощью параметра ProtectTo. Если вы используете пароль, вы сначала превращаете его в безопасную строку: $CertPW = ConvertTo-SecureString -String "secret" ` -Force -AsPlainText Затем он передается в параметр Password при вызове Export-PfxCertificate: Export-PfxCertificate -Password $CertPW ` -Cert cert:\LocalMachine\My\ myCert.pfx Вы указываете сертификат через путь в хранилище и его отпечаток.

Экспорт самоподписанного сертификата в файл PFX Если вы используете самозаверяющий сертификат на сервере, клиенты не считают его заслуживающим доверия. Чтобы обойти соответствующее предупреждение, вы можете импортировать его в доверенные корневые центры сертификации на клиентах либо вручную, либо через GPO. Для этого экспортируйте сертификат без закрытого ключа в DER-кодированном формате: Export-Certificate -FilePath MyCert.cer ` -Cert Cert:\LocalMachine\My\ В Windows расширение имени для такого файла экспорта обычно ".cer".

3.4 Удаленное взаимодействие через HTTPS с самозаверяющим сертификатом WinRM шифрует данные по умолчанию и поэтому безопасен, даже если вы работаете только с HTTP (что является стандартной конфигурацией). В частности, в рабочих группах вы можете обеспечить дополнительную безопасность с помощью HTTPS, при этом самоподписанного сертификата должно быть достаточно в большинстве случаев. Действительно, документация Microsoft для Invoke-Command (bit.ly/3fVd2d1) подтверждает, что WSManagement шифрует все передаваемые данные PowerShell. К сожалению, при неправильной настройке удаленное взаимодействие PowerShell небезопасно, и в некоторых случаях вам необходимо изменить конфигурацию по умолчанию. Чтобы проверить, как настроены ваши машины, вы можете запустить эту команду: winrm get winrm/config

Проверка конфигурации WinRM Вы также можете просмотреть конфигурацию в PowerShell: dir WSMan:\localhost\Service | ? Name -eq AllowUnencrypted

Запросите текущую конфигурацию WS-Management с помощью PowerShell. Для клиента соответствующая команда

dir WSMan:\localhost\Client | ? Name -eq AllowUnencrypted

3.4.1 Дополнительная защита для сред рабочих групп Вторая и, на мой взгляд, более серьезная проблема заключается в том, что если вы работаете с машинами, которые не входят в домен Active Directory, у вас нет доверительных отношений с удаленными компьютерами. В этом случае вы имеете дело только с симметричным шифрованием, поэтому атаки «человек посередине» теоретически возможны, поскольку сначала необходимо передать ключ. Там вы должны добавить удаленные машины, которые не находятся в домене Active Directory, в список TrustedHosts на клиенте. Однако вы не улучшите безопасность, просто определив IP-адреса или имена компьютеров как заслуживающие доверия. Это просто дополнительное препятствие, которое Microsoft добавила, чтобы вы знали, что собираетесь сделать что-то рискованное. Вот тут и приходит на помощь PowerShell Remoting через SSL. Во-первых, HTTPS-трафик всегда шифруется. Таким образом, вы всегда можете автоматизировать свои задачи удаленно, не беспокоясь. А поскольку SSL использует асимметричное шифрование и сертификаты, вы можете быть уверены, что безопасно и напрямую подключены к удаленному компьютеру, а не к компьютеру злоумышленника, который перехватывает и ретранслирует ваш трафик. С другой стороны, настроить PowerShell Remoting для использования с SSL немного сложнее, чем просто запустить Enable-PSRemoting. Основная проблема в том, что вам нужен SSL-сертификат. Если вы просто хотите управлять некоторыми автономными серверами или рабочими станциями, вы, вероятно, не захотите приобретать публично подписанный сертификат и вместо этого захотите работать с самозаверяющим сертификатом. Однако теперь вы увидите, что включить SSL для WinRM на клиенте и на сервере не так уж и сложно (хотя и не так просто, как с SSH), и все это можно сделать с помощью встроенных командлетов PowerShell. Вам даже не понадобится пресловутый инструмент командной строки Windows winrm.

3.4.2 Включение HTTPS на удаленном компьютере Первое, что нам нужно сделать, это создать SSL-сертификат. Если у вас есть публично подписанный сертификат, все проще, и вы можете использовать Set-WSManQuickConfig -UseSSL Как было сказано выше, с момента выпуска PowerShell 4 нам не требуются сторонние инструменты для выпуска самоподписанного сертификата. Командлет New-SelfSignedCertificate — это все, что нам нужно: $Cert = New-SelfSignedCertificate -DnsName "myHost" ` -CertstoreLocation Cert:\LocalMachine\My Важно передать имя компьютера, которым вы хотите управлять удаленно, в параметр -DnsName. Если у компьютера есть DNS-имя, следует использовать полное доменное имя (FQDN).

Выпустите самозаверяющий сертификат, экспортируйте его и создайте прослушиватель HTTPS для удаленного взаимодействия PowerShell. При желании вы можете проверить правильность хранения сертификата с помощью надстройки сертификата консоли управления Microsoft (MMC). Введите mmc на начальном экране и добавьте надстройку «Сертификаты» для учетной записи компьютера и локального компьютера. Сертификат должен находиться в папке «Personal\Certificates».

Сертификат в MMC на удаленном компьютере Теперь нам нужно экспортировать сертификат в файл, потому что позже нам придется импортировать его на наш локальный компьютер. Вы можете сделать это с помощью надстройки MMC, но мы сделаем это в PowerShell: Export-Certificate -Cert $Cert -FilePath C:\temp\cert Имя файла здесь не имеет значения. Нам нужен сертификат для запуска прослушивателя HTTPS WS-Management. Но сначала мы должны включить удаленное взаимодействие PowerShell на хосте: Enable-PSRemoting -SkipNetworkProfileCheck -Force Переключатель -SkipNetworkProfileCheck гарантирует, что PowerShell не будет жаловаться, если для вашего типа сетевого подключения установлено значение Public.

Enable-PSRemoting также запускает прослушиватель WS-Management, но только для HTTP. Если вы хотите, вы можете убедиться в этом, прочитав содержимое диска WSMan: dir wsman:\localhost\listener

Список слушателей WSMan Чтобы убедиться, что никто не использует HTTP для подключения к компьютеру, вы можете удалить прослушиватель HTTP следующим образом: Get-ChildItem WSMan:\Localhost\listener | Where -Property Keys -eq "Transport=HTTP" | Remove-Item -Recurse Эта команда удаляет всех слушателей WSMan: Remove-Item -Path WSMan:\Localhost\listener\listener* ` -Recurse Затем мы добавляем наш прослушиватель HTTPS WSMan: New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * CertificateThumbPrint $Cert.Thumbprint -Force Мы используем переменную $Cert, которую мы определили ранее, для чтения отпечатка, что позволяет командлету New-Item найти сертификат в нашем хранилище сертификатов. Последнее, что нам нужно сделать, это настроить брандмауэр на хосте, потому что командлет EnablePSRemoting добавил только правила для HTTP: New-NetFirewallRule -LocalPort 5986 -Protocol TCP ` -DisplayName "Windows Remote Management (HTTPS-In)" ` -Name "Windows Remote Management (HTTPS-In)" -Profile Any

Создайте новое правило брандмауэра для удаленного взаимодействия PowerShell через HTTPS. Обратите внимание, что мы разрешаем входящий трафик через порт 5986. WinRM 1.1 (текущая версия — 3.0) использовала общий HTTPS-порт 443. Вы по-прежнему можете использовать этот порт, если хост находится за брандмауэром шлюза, который блокирует порт 5986: Set-Item WSMan:\localhost\Service\EnableCompatibility-HttpsListener -Value true Конечно, вам нужно открыть порт 443 в брандмауэре Windows. Обратите внимание, что эта команда не будет работать, если для типа сетевого подключения на этом компьютере установлено значение Public. В этом случае вы должны изменить тип подключения на частный: Set-NetConnectionProfile -NetworkCategory Private Из соображений безопасности вы можете отключить правило брандмауэра для HTTP, добавленное Enable-PSRemoting: Disable-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)" Наш удаленный компьютер теперь готов к удаленному взаимодействию PowerShell через HTTPS, и мы можем настроить наш локальный компьютер.

3.4.3 Активируйте HTTPS на локальном компьютере Здесь все немного проще. Во-первых, вам нужно скопировать файл сертификата туда, куда мы экспортировали наш сертификат. Затем вы можете импортировать сертификат с помощью этой команды: Import-Certificate -Filepath "C:\temp\cert" ` -CertStoreLocation "Cert:\LocalMachine\Root" Обратите внимание, что нам нужно хранить сертификат в папке «Доверенные корневые центры сертификации» здесь, а не в папке «Личные», как мы сделали на удаленном компьютере. Ваш компьютер доверяет всем машинам, которые могут подтвердить свою подлинность с помощью своих закрытых ключей (хранящихся на хосте) и хранящихся здесь сертификатов.

Сертификат в MMC на локальном компьютере Кстати, именно поэтому нам не нужно добавлять удаленную машину в список TrustedHosts. В отличие от PowerShell Remoting через HTTP, мы можем быть уверены, что удаленная машина является той, за которую она себя выдает. Это основной момент использования HTTPS вместо HTTP. Теперь мы готовы войти в сеанс PowerShell на удаленной машине через HTTPS: Enter-PSSession -ComputerName myHost ` -UseSSL -Credential (Get-Credential) Ключевым параметром здесь является -UseSSL. Конечно, нам все еще нужно пройти аутентификацию на удаленной машине с учетной записью администратора. Вы можете получить это сообщение об ошибке: The SSL certificate is signed by an unknown certificate authority. В этом случае вы можете просто добавить параметр -SkipCACheck. Командлет Invoke-Command также поддерживает параметр -UseSSL: Invoke-Command -ComputerName myHost -UseSSL ` -ScriptBlock {Get-Process} Credential (Get-Credential)

3.4.4 Заключение HTTPS не просто добавляет еще один уровень шифрования; его основная цель — проверить подлинность удаленной машины, тем самым предотвращая атаки «человек посередине». Таким образом, вам нужен HTTPS только в том случае, если вы используете PowerShell Remoting через небезопасную территорию. Внутри вашей локальной сети, с доверительными отношениями между членами домена Active Directory, WSMan через HTTP достаточно безопасен.

4 Достаточное администрирование 4.1 Конфигурация сеанса JEA Если пользователи хотят подключиться к удаленному ПК через PowerShell без прав администратора, им это не удастся из-за недостаточных прав. Это ограничение можно устранить с помощью конфигураций

сеанса. Тем самым не нужно предоставлять обычным пользователям доступ ко всем функциям PowerShell. Возможность удаленного управления — одна из сильных сторон PowerShell. Он не ограничивается интерактивными сеансами, в которых команды выполняются на удаленном компьютере. Скорее, он также позволяет запускать сценарии для автоматизации задач.

4.1.1 Конфигурации сеанса как компонент JEA По умолчанию эта опция недоступна для обычных пользователей, и их запросы будут отклонены целевым компьютером. Однако, если вы хотите делегировать задачи сотрудникам без административных привилегий, вы должны ослабить это строгое правило.

По умолчанию пользователи без прав администратора не могут установить удаленный сеанс с PowerShell. Конфигурация сеанса служит этой цели. Он определяет, кому разрешено устанавливать сеанс на компьютере. Эту функцию также выполняет Just Enough Administration (JEA). JEA определяет, что пользователям разрешено делать там, с помощью дополнительных файлов возможностей ролей. Однако во многих случаях вам не нужно иметь дело с полным JEA, но вы можете определить права доступа и доступные языковые элементы непосредственно через конфигурацию сеанса.

4.1.2 Стандартные конфигурации с ограничениями Определения сеансов всегда контролируют доступ PowerShell к компьютеру, даже если вы не создали свой собственный. По умолчанию на каждом компьютере с Windows существует три конфигурации сеанса, а именно microsoft.powershell, microsoft.powershell.workflow и microsoft.windows.servermanagerworkflows. Если вы создаете новый сеанс, например с помощью Enter-PSSession, и не указываете конкретную конфигурацию, по умолчанию вступает в силу microsoft.powershell. Как видно из команды Get-PSSessionConfiguration на целевом компьютере эта конфигурация сеанса зарезервирована для администраторов и членов локальной группы «Remote Administration Users».

Отображение существующих конфигураций сеанса и их авторизации с помощью GetPSSessionConfiguration

4.1.3 Определение собственных конфигураций Теоретически теперь вы можете просто изменить параметры безопасности этой конфигурации, чтобы предоставить доступ для выбранных стандартных пользователей. Но от этого стоит воздержаться и поддерживать рабочую конфигурацию для админов. Самый простой способ создать новую конфигурацию сеанса — выполнить команду в соответствии со следующим шаблоном на целевом компьютере (также называемом конечной точкой на жаргоне JEA): Register-PSSessionConfiguration -Name HelpDesk

Создайте новую конфигурацию сеанса с помощью Register-PSSessionConfiguration. Эта команда мало что дает, поскольку новая конфигурация является лишь копией microsoft.powershell и не позволяет пользователям, кроме администраторов, получить доступ к компьютеру. Следовательно, вы должны определить разрешения при создании конфигурации.

4.1.4 Определение разрешений Это делается с помощью параметра SecurityDescriptorSddl, но для этого требуются разрешения в синтаксисе языка определения дескрипторов безопасности (bit.ly/33Xti8f). Если вам не нужно создавать конфигурации сеанса слишком часто, вы можете сэкономить эти усилия и вместо этого использовать параметр ShowSecurityDescriptorUI: Register-PSSessionConfiguration -Name HelpDesk ` -ShowSecurityDescriptorUI Откроется диалоговое окно, которое вы уже знаете по управлению правами доступа к файлам.

Управление разрешениями для конфигурации сеанса

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

4.1.5 Определение пользователей RunAs До сих пор вы уже настроили, кому разрешено начинать сеанс на этом удаленном компьютере, используя новую конфигурацию. Кроме того, вы также можете указать, под каким ID пользователя это должно происходить, передав соответствующий ID в параметр RunAsCredential: Register-PSSessionConfiguration -Name HelpDesk ` -RunAsCredential contoso\FLee

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

4.1.6 Принудительные ограничения для сессий Работа под другой учетной записью может дать пользователям разные разрешения в файловой системе, но функциональные ограничения, налагаемые конфигурацией сеанса, применяются независимо от используемой учетной записи. Поэтому учетная запись RunsAs не требует никаких разрешений в дескрипторе безопасности конфигурации сеанса. Командлет Register-PSSessionConfiguration предоставляет несколько параметров, которые можно использовать для ограничения возможностей пользователей.  MaximumReceivedDataSizePerCommandMB: указывает максимальный объем данных в МБ, которые можно передать с помощью одной команды (по умолчанию: 50 МБ).  MaximumReceivedObjectSizeMB: определяет максимальный размер одного объекта, который может быть передан (по умолчанию: 10 МБ).

 SessionType: определяет, какие модули и оснастки доступны в сеансе. Их нет, если значение пустое (и должно быть явно добавлено с использованием, например, параметра ModulesToImport). По умолчанию пользователи могут сами расширять функциональность с помощью Import-Module. Наконец, RestrictedRemoteServer предоставляет полдюжины командлетов. Все описанные здесь параметры, кроме имени, также можно использовать позже для настройки конфигурации с помощью Set-SessionConfiguration.

4.1.7 Дополнительные опции через конфигурационный файл Во многих случаях Register-PSSessionConfiguration может создать необходимый контекст для выполнения пользователями определенных задач на удаленном узле. В качестве дополнительной опции вы можете запустить скрипт при запуске сессии (параметр StartupScript). Но если этого недостаточно, в файле конфигурации доступны дополнительные параметры. Его можно создать с помощью командлета New-PSSessionConfigurationFile. Вы можете передать желаемые настройки в файл конфигурации либо в виде параметров, либо запустить его в такой минималистичной форме: New-PSSessionConfigurationFile -Path .\MyConfig.pssc Имя файла требует расширения .pssc. Затем откройте файл в текстовом редакторе и добавьте нужные настройки, некоторые из которых уже доступны и закомментированы.

Файл по умолчанию, созданный New-PSSessionConfigurationFile Следующие действия особенно полезны для предотвращения потенциально опасных действий пользователей:  LanguageMode со значениями FullLanguage, RestrictedLanguage, ConstrainedLanguage, NoLanguage: последний разрешает только выполнение командлетов и функций, другие языковые ресурсы недоступны. FullLanguage предлагает полный спектр языковых возможностей, два других лежат между этими двумя полюсами.

 VisibleAliases, VisibleCmdlets, VisibleFunctions, VisibleProviders: позволяют указать, какие псевдонимы, командлеты, функции и поставщики доступны в сеансе. Вы можете использовать подстановочные знаки и указывать несколько значений в виде массива.

4.1.8 Ограничение доступа к командлетам Чтобы ограничить доступные командлеты теми, которые только читают, а не пишут, вы можете использовать выражение Get*, Select*: New-PSSessionConfigurationFile -Path .\MyConfig.pssc ` -VisibleCmdlets "Get*","Select*" Затем вы настраиваете конфигурацию сеанса на основе этого файла: Set-PSSessionConfiguration -Name HelpDesk ` -Path .\MyConfig.pssc

Создайте файл конфигурации и назначьте его новой конфигурации сеанса. Если вы сейчас попытаетесь установить интерактивный удаленный сеанс с компьютером, у вас ничего не получится, потому что доступны не все необходимые команды: Enter-PSSession -ComputerName remote-pc ` -ConfigurationName HelpDesk

Сокращенного набора функций недостаточно для интерактивного сеанса.

Таким образом, пользователь с такой конфигурацией сеанса может удаленно выдавать команды, например, с помощью такой команды: Invoke-Command -ComputerName remote-pc ` -ConfigurationName Helpdesk {Get-ChildItem}

Выдача команды удаленно в ограниченном сеансе с помощью Invoke-Command

4.1.9 Назначение конфигурации сеансу Как показывают две приведенные выше команды, вы должны указать желаемую конфигурацию сеанса, используя параметр ConfigurationName. Если вы этого не сделаете, будет применен microsoft.powershell, и пользователи без прав администратора будут исключены. Но вы можете указать, какая конфигурация используется по умолчанию, с помощью переменной $PSSessionConfigurationName. Наконец, вы можете удалить конфигурации сеанса, которые вам больше не нужны, с помощью командлета Unregister-PSSessionConfiguration. В качестве аргументов требуется только имя конфигурации.

4.2 Определение и назначение ролевых функций Just Enough Administration (JEA) позволяет пользователям без прав администратора выполнять задачи управления. JEA основан на конфигурациях сеансов, которые определяют, кто получает доступ. Затем возможности ролей определяют средства, доступные для них в PowerShell. Вы уже можете управлять некоторыми свойствами при создании или изменении конфигурации сеанса с помощью Register-PSSessionConfiguration или Set-PSSessionConfiguration. Вы получаете больше возможностей, используя файл конфигурации (.pssc). Здесь можно применить определенный языковой режим или ограничить доступ к определенным командлетам. Однако если вам нужен более сложный набор правил для адаптации параметров сеанса к потребностям конкретных задач, вам следует определить ролевые функции в отдельном файле .psrc.

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

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

4.2.2 Создание файла возможностей роли Файлы с расширением .psrc для описания возможностей роли являются текстовыми файлами. Файл скелета можно создать с помощью команды: New-PSRoleCapabilityFile -Path MyRCF.psrc Он содержит все доступные параметры плюс соответствующее описание в форме комментариев, так что вы можете сразу редактировать их в редакторе. При создании файла вы также можете использовать многочисленные параметры New-PSRoleCapabilityFile (bit.ly/2NTpO12) для установки различных параметров.

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

4.2.3 Компиляция VisibleCmdlets через графический интерфейс Если вы хотите вручную ввести такую подробную информацию в файл .psrc, это займет относительно много времени. Эту работу упрощает JEA Helper Tool, скрипт PowerShell с графическим интерфейсом. На вкладке Role Capabilities Design вы можете в интерактивном режиме составить список командлетов, которые разрешено просматривать пользователям определенного сеанса.

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

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

4.2.4 Сохранение файла возможностей роли Создав список разрешенных командлетов и параметров, вы можете добавить их в файл .psrc. Вы сохраняете этот файл в каталоге с именем RoleCapabilities под $env:ProgramFiles\WindowsPowerShell\Modules

4.2.5 Назначение ролевых функций конфигурации сеанса Последний шаг — связать возможности роли с желаемой конфигурацией сеанса. Для этого отредактируйте конфигурационный файл с расширением .pssc и добавьте туда ролевые функции. Поскольку вы создаете этот файл автоматически в начале, этот (закомментированный) раздел для RoleDefinitions уже должен быть там: # RoleDefinitions = @{ 'CONTOSO\SqlAdmins' = ` @{ RoleCapabilities = 'SqlAdministration' }; 'CONTOSO\SqlManaged' = @{ RoleCapabilityFiles = 'C:\RoleCapability\SqlManaged.psrc' }; 'CONTOSO\ ServerMonitors' = `

@{VisibleCmdlets = 'Get-Process' } } Следуя тому же шаблону, вы теперь добавляете свою собственную запись, при этом у вас есть 3 варианта, как показано в примере. Последний из них определяет разрешенные командлеты непосредственно в файле конфигурации сеанса и поэтому неприменим, если вы используете файл .psrc. Если вы сохраните файл .psrc под именем SqlManaged.psrc в пути к модулю, как описано выше, запись может выглядеть следующим образом: RoleDefinitions = @{ 'contoso\SqlAdmins' = ` @{ RoleCapabilities = 'SqlAdministration' }}; Это дает группе SqlAdmins из домена contoso возможности роли, определенные в SqlManaged.psrc.

Параметры для определения возможностей роли в файле конфигурации сеанса Если вы выбрали другое место для сохранения файла, вам нужно действовать, как показано в последней записи в примере, и ввести имя файла, включая путь, в качестве значения для RoleCapabilityFiles. Наконец, вам нужно обновить конфигурацию сеанса, используя следующую команду: Set-PSSessionConfiguration -Name MySessionConfig ` -Path .\MyConfig.pssc

5 Аудит действий PowerShell 5.1 Записывать команды в файл транскрипции Чтобы обнаружить злоупотребление PowerShell, вы можете записывать все выполняемые команды и сценарии. Для этого есть два механизма, один из них записывает весь ввод и вывод в файл. Собранные данные рекомендуется хранить в центральном месте. Microsoft описывает форму записи, при которой PowerShell регистрирует все обработанные входные данные и результирующие выходные данные в одном файле, как «транскрипцию через плечо». Этот

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

5.1.1 Активация ведения журнала с помощью командлета Этот вариант существует с первых дней существования PowerShell, и в прошлом им можно было управлять только явно с помощью командлетов Start-Transcript и Stop-Transcript. Чтобы включить автоматическую запись команд, вам нужно было включить вызов Start-Transcript в профиль PowerShell. Это не только громоздко, если вам нужно настроить таким образом много машин, но и злоумышленнику относительно легко обойти этот метод. Однако явный запуск и остановка записи с помощью командлета может оказаться полезным, если вы включите его в свои собственные сценарии, чтобы увидеть, какие выходные данные они производят.

5.1.2 Включение транскриптов через GPO Начиная с PowerShell 5, вы можете включить стенограммы с помощью групповой политики. Соответствующий параметр называется «Включить транскрипцию PowerShell» и находится в разделе Policies => Administrative Templates => Windows Components => Windows PowerShell.

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

5.1.3 Собственный файл журнала для каждого сеанса По умолчанию эта функция создает каталог в профиле пользователя на каждый день и записывает записи для каждого сеанса в отдельный текстовый файл, имя которого состоит из «PowerShell_transcript», плюс имя хоста компьютера и случайное число.

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

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

Каждый получает только права «Чтение» и «Запись». В частности, вы должны действовать следующим образом:  Отключите наследование для настроенного каталога журналов, удалите все существующие разрешения.  Администраторы получают полный доступ  Каждый получает право «Писать»  Владелец-создатель лишен всех прав

Разрешения для каталога журналов PowerShell Другим вариантом для параметров Start-Transcript и GPO является запись заголовка для каждого вызова. Он содержит метку времени для соответствующей команды.

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

5.1.5 GPO не работает для PowerShell 6/7 Административный шаблон PowerShellExecutionPolicy.admx записывает только значения реестра для Windows PowerShell, поэтому EnableTranscripting не влияет на PowerShell Core или PowerShell 7. Поэтому для версии 6 вы должны самостоятельно установить требуемый ключ в реестре. В следующем содержимом файла .reg показаны имена двух DWORD и путь, по которому вы должны их создать. Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Pow-erShellCore\ Transcription] "EnableTranscripting"=dword:00000001 "OutputDirectory"="\\server\\pslogs" Если вы хотите установить эти параметры на большем количестве компьютеров, рекомендуется настроить реестр с помощью настроек групповой политики. PowerShell 7 поставляется с собственным шаблоном ADMX, который можно скопировать в %systemroot %\policydefinitions или в центральное хранилище. Параметры версии 7 находятся в редакторе GPO непосредственно в разделе «Административные шаблоны» в контейнере PowerShell Core (как для компьютера, так и для пользователя).

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

5.2 Ведение журнала Scriptblock: запись команд в журнал событий Для обнаружения подозрительных действий полезно записывать все выполняемые команды. Помимо записи истории в текстовый файл, PowerShell также поддерживает ведение журнала событий, начиная с версии 5. PowerShell v5 включает несколько нововведений в ведение журнала. Он расширил старый метод, так называемую «транскрипцию через плечо», на все хосты PS, включая ISE, и, следовательно, больше не ограничивался командной строкой. Кроме того, эту функцию теперь также можно активировать с помощью групповых политик.

5.2.1 Регистрация фактических команд Запись всех команд в текстовый файл была дополнена так называемой глубокой записью скриптовых блоков. Он не только использует журнал событий Windows вместо текстового файла, но и записывает все команды точно так, как они выполняются PowerShell. Таким образом, вредоносная активность не может остаться незамеченной. Это относится, например, к использованию динамической генерации кода, когда команды сохраняются в переменной, а затем выполняются с помощью Invoke-Expression. Эта функция также выявляет попытки скрыть последовательности команд путем их кодирования с использованием Base64.

5.2.2 Активация только через GPO Хотя транскрипцию также можно явно включать и выключать с помощью командлетов Start-Transcript и Stop-Transcript, вы можете включить ведение журнала блока сценариев только с помощью объектов групповой политики или путем прямой установки соответствующего раздела реестра. Таким образом, все еще существует потребность в более старом методе, таком как запись вывода в ваших собственных сценариях.

Групповая политика для включения глубокого ведения журнала блоков сценариев Соответствующий параметр объекта групповой политики называется «Включить ведение журнала блоков сценариев PowerShell» и находится в разделе «Политики» > «Административные шаблоны» > «Компоненты Windows» > «Windows PowerShell». Если вы настраиваете его в разделе «Конфигурация компьютера и пользователя», преобладает предыдущий параметр. Если вы выберете вариант для запуска/остановки, то вы должны ожидать значительно больший объем данных, поскольку в журнал будут записываться маркеры начала и остановки всех событий.

5.2.3 Подготовка журнала событий Пока вы готовите ведение журнала в текстовых файлах, создавая каталог в общем файловом ресурсе и назначая необходимые права доступа, для более нового ведения журнала требуется другая подготовительная работа. Начните с изменения максимального размера журнала событий с 20 МБ по умолчанию на значительно большее значение. Это необходимо по двум причинам: во-первых, в зависимости от конфигурации функции ведения журнала накапливается относительно большой объем данных. Во-вторых, злоумышленники не должны иметь возможности просто замести следы, относительно быстро заполняя журнал ничего не подозревающими записями.

Поскольку оценка журналов предоставляется либо сценариям, разработанным для этой цели, либо инструментам SIEM, записанные события необходимы в центральном месте. Для этого перенаправьте записи, написанные PowerShell, на компьютер в сети.

Ведение журнала выполняется в PowerShell/Operational.

5.2.4 Идентификаторы событий Регистрация происходит в журнале приложений в Microsoft => Windows => PowerShell => Operational, а команды записываются под идентификатором события 4104. Если вы также записываете события запуска и остановки, они отображаются под идентификаторами 4105 и 4106.

Пользовательский фильтр в просмотрщике событий для записанных блоков сценария

Если вы хотите настроить определяемый пользователем фильтр для записанных команд в средстве просмотра событий, активируйте как источник  PowerShell (Microsoft-WindowsPowerShell),  PowerShell (PowerShell)  PowerShellCore Кроме того, выберите «Предупреждение» в качестве типа события и введите 4104 в качестве идентификатора.

5.2.5 Объединение последовательностей команд В то время как стенограммы могут записывать свои данные в текстовый файл практически без ограничений, поле блока сценария в журнале событий ограничивает длину записи. Поэтому более длинные сценарии разделены и охватывают несколько записей. В Microsoft Docs есть шаблон сценария PowerShell, который можно использовать для повторной сборки фрагментов журнала. Если, например, вы хотите объединить все записи для процесса с идентификатором 6524, вы можете действовать следующим образом: $created = Get-WinEvent -FilterHashtable ` @{ProviderName="Microsoft-Windows-PowerShell"; Id=4104} | where ProcessId -eq 6524 $sortedScripts = $created | sort {$_.Properties[0].Value} $mergedScript = -join ($sortedScripts | foreach {$_.Properties[2].Value})

5.2.6 Ведение журнала блоков сценариев для PowerShell Core Как и в случае расшифровок, групповая политика разрешает ведение журнала блоков сценариев только для Windows PowerShell. Это не влияет на PowerShell Core 6.x и его преемника PowerShell 7. Если вы хотите записывать команды для версии 6.x в журнал событий, вы должны сами установить раздел реестра. Для этого создайте ключ ScriptBlockLogging в разделе HKLM\SOFTWARE\Policies\Microsoft\PowerShellCore и присвойте значение 1 EnableScriptBlockLogging. Следующие инструкции в файле .reg помогут выполнить эту задачу: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Pow-erShellCore\ ScriptBlockLogging] "EnableScriptBlockLogging"=dword:00000001 С другой стороны, PowerShell 7 включает собственный шаблон ADMX, который можно скопировать в %systemroot%\policydefinitions или в центральное хранилище. Он содержит все настройки, известные из PowerShell 5, в том числе для ведения журнала блоков сценариев.

Параметры групповой политики для PowerShell 7 Наконец, следует отметить, что записи журнала для PowerShell Core расположены непосредственно в журналах приложений и служб. Идентификаторы событий для ведения журнала такие же, как для Windows PowerShell.

5.3 Выдача сертификатов для шифрования документов Начиная с версии 5, PowerShell поддерживает стандартный синтаксис криптографических сообщений (CMS) IETF для шифрования данных или записей журнала. Для этого требуется сертификат, который был выпущен специально для этой цели. Если вы хотите запросить сертификат у ЦС Windows, вы должны сначала настроить для него шаблон. В инструкциях Microsoft, например, для Protect-CmsMessage (bit.ly/2XPVQzB) всегда описывается процедура выдачи самоподписанного сертификата с помощью certreq.exe для шифрования документов. Они упаковывают данные для запроса сертификата в INF-файл по следующему шаблону: [Version] Signature = "$Windows NT$" [Strings] szOID_ENHANCED_KEY_USAGE = "2.5.29.37" szOID_DOCUMENT_ENCRYPTION = "1.3.6.1.4.1.311.80.1" [NewRequest] Subject = "[email protected]" MachineKeySet = false KeyLength = 2048 KeySpec = AT_KEYEXCHANGE HashAlgorithm = Sha1 Exportable = true RequestType = Cert KeyUsage = "CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_DATA_ENCIPHERMENT_KEY_USAGE"

ValidityPeriod = "Years" ValidityPeriodUnits = "1000" [Extensions] %szOID_ENHANCED_KEY_USAGE% = "{text}%szOID_DOCUMENT_EN-CRYPTION%" Чтобы запросить сертификат, используйте команду: certreq -new .inf .cer Сертификат автоматически копируется в локальное хранилище сертификатов вошедшего в систему пользователя. При необходимости вы можете экспортировать его и перенести через GPO на компьютеры, на которых вы хотите зашифровать данные (bit.ly/30OQJ4o).

5.3.1 Создание шаблона ЦС предприятия Если вы предпочитаете сертификат, выданный внутренним ЦС Windows, а не самоподписанный сертификат, по умолчанию требуемый шаблон отсутствует. Если вы хотите создать его, вы можете следовать настройкам вышеуказанного файла .inf. Сначала откройте консоль шаблонов сертификатов, certtmpl.msc, и продублируйте подходящий существующий шаблон. В нашем примере мы будем использовать шаблон User.

Дублировать существующий шаблон в качестве основы для нового шаблона для шифрования документов Затем присвойте имя новому шаблону на вкладке «Общие» и определите срок действия шаблона.

Присвоить имя новому шаблону Затем измените цель на вкладке «Обработка запросов» на «Шифрование». Здесь вы также можете разрешить экспорт закрытого ключа, если сертификаты для шифрования документов необходимы на нескольких компьютерах для расшифровки документов.

Измените назначение шаблона сертификата на «Шифрование». Как и в показанном выше файле .inf, длина ключа должна быть не менее 2048 бит; соответствующий параметр находится на вкладке Криптография. Настройте необходимые параметры на вкладке «Расширения». Здесь мы редактируем политики приложений и удаляем все существующие записи. Вместо этого мы добавляем шифрование документов.

В политики приложений добавлено шифрование документов По умолчанию новый сертификат используется для шифрования сертификатов CERT_KEY_ENCIPHERMENT_KEY_USAGE в файле .inf, чего достаточно для описанной здесь задачи. Если вы хотите добавить CERT_DATA_ENCIPHERMENT_KEY_USAGE, отредактируйте запись «Использование ключа» и выберите параметр «Разрешить шифрование данных пользователя» в следующем диалоговом окне.

Включить шифрование пользовательских данных при использовании ключей Наконец, используйте вкладку «Безопасность», чтобы убедиться, что все пользователи, запрашивающие сертификат на основе этого шаблона, имеют разрешения «Чтение» и «Регистрация».

5.3.2 Запрос сертификата Теперь вы можете запросить свой сертификат с помощью certmgr.msc. Если вы не можете найти новый шаблон в списке или он имеет статус «Недоступен» в расширенном представлении, воспользуйтесь этим советом по устранению неполадок. В деталях введите имя субъекта в формате, указанном в шаблоне. В разделе Закрытый ключ => Параметры ключа убедитесь, что он доступен для экспорта, если это необходимо.

Запрос сертификата на основе нового шаблона После того, как вы нажмете Enroll, новый сертификат должен появиться в хранилище Текущего Пользователя.

5.4 Шифрование журналов событий и файлов с помощью PowerShell и GPO В Windows 10 и Server 2016 появилась функция защищенного ведения журнала событий, которая шифрует конфиденциальные данные в журнале событий. Он использует открытый стандартный синтаксис криптографических сообщений (CMS), который PowerShell поддерживает с несколькими командлетами. Вы также можете использовать их для шифрования или расшифровки файлов. Вы можете задаться вопросом, почему вы должны шифровать файлы журнала Windows. Эта функция была активирована введением ведения журнала блоков сценариев в PowerShell 5, при котором все введенные команды сохраняются в журнале событий. Эти команды могут также включать учетные данные, которые не должны быть видны посторонним лицам.

5.4.1 Активация через групповые политики По сути, защищенное ведение журнала событий — это общесистемная функция, которую могут использовать все приложения и службы Windows. Если вы активируете его в Windows 10, PowerShell в настоящее время является единственным пользователем этого шифрования. Чтобы включить безопасное ведение журнала событий, Microsoft предоставляет параметр в групповой политике. Он называется «Включить защищенное ведение журнала событий» и находится в разделе «Конфигурация компьютера» => «Политики» => «Административные шаблоны» => «Компоненты Windows» => «Журнал событий».

Шифрование записей PowerShell в журнале событий можно включить с помощью групповых политик. Для успешной активации этого параметра требуется сертификат, специально выпущенный для шифрования документов. Его открытый ключ используется для кодирования записей журнала. Редактор GPO допускает несколько способов привязки политики к сертификату. Вы можете сохранить его в общей папке и указать путь к нему. Если сертификат доступен в магазине локального компьютера, достаточно будет и отпечатка пальца пользователя. Простой способ — экспорт сертификата в закодированном виде Base64, содержимое которого можно просто скопировать в текстовое поле.

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

Средство просмотра событий представляет только зашифрованные записи; он не может их расшифровать Поэтому вы должны сделать эти записи журнала доступными для чтения с помощью PowerShell. Командлет Unprotect-CmsMessage, противоположный Protect-CmsMessage, расшифровывает их. Например, если вы хотите расшифровать последнюю запись в журнале PowerShell, вы можете получить ее с помощью Get-WinEvent и направить в Unprotect-CmsMessage: $msg = Get-WinEvent ` Microsoft-Windows-PowerShell/Operational ` -ComputerName myPC -MaxEvents 2 -Credential domain\user "Last log entry as clear text:" $msg[1] | select -ExpandProperty Message | Unprotect-CmsMessage # $msg[0] is always "prompt"

Расшифровка журналов PowerShell с помощью Unprotect-CmsMessage Полный скрипт для этой цели можно найти в блоге Эмина Атака (bit.ly/2DM85Gx). Проблема с ведением журнала блоков сценариев заключается в том, что более длинные последовательности команд разбиваются на несколько записей журнала. Поэтому в этом случае вам придется агрегировать отдельные разделы, а затем передавать их в Unprotect-CmsMessage.

5.4.3 Шифрование файлов Protect-CmsMessage также можно использовать для шифрования любого файла. Если их содержимое двоичное, то вам следует сначала преобразовать его в представление Base64. Сценарии использования здесь также могут включать защиту конфиденциальных данных в сценариях или файлах паролей от несанкционированного доступа. Однако эта технология определенно не предназначена в качестве альтернативы шифрующей файловой системе или даже Bitlocker. Поскольку PowerShell использует стандартный синтаксис криптографических сообщений, вы можете расшифровывать закодированные файлы с помощью других инструментов на разных платформах, таких как OpenSSL в Linux (bit.ly/2E21l6Y). Поэтому эта функция PowerShell подходит и для обмена конфиденциальными данными между разными операционными системами. Процесс относительно прост. Protect-CmsMessage ожидает входной файл через параметр Path. Кроме того, вы можете предоставить содержимое для шифрования с помощью параметра Content или через конвейер. Целевой файл указывается через OutFile; в противном случае выводится стандартный вывод.

Простое применение Protect-CmsMessage и Unprotect-CmsMessage Другая необходимая информация включает сертификат, который вы хотите использовать. Этой цели служит параметр To, который принимает отпечаток пальца, имя субъекта или путь к сертификату. И наоборот, Unprotect-CmsMessage требуется только содержимое для расшифровки (через содержимое или путь); передача его через трубу также возможна. Параметр To можно опустить, если сертификат находится в локальном хранилище.

5.4.4 Проблемы с набором символов Следите за кодировкой файлов. В противном случае вы будете удивлены искаженным результатом после расшифровки. Так обстоит дело, например, со следующей процедурой: Get-Process > process.txt Protect-CmsMessage -Path process.txt -out process.enc ` -To 61F4C2FFF9CC… Unprotect-CmsMessage -Path process.enc

Неправильная кодировка символов уничтожает контент при шифровании и дешифровании Чтобы избежать таких нежелательных эффектов, сохраните вывод, используя: Get-Process | Out-File -FilePath process.txt ` -Encoding utf8 Если вы предпочитаете первый вариант с перенаправлением в файл, то вы должны преобразовать содержимое в правильный набор символов при чтении для шифрования: Get-Content -Raw -Encoding UTF8 process.txt | Protect-CmsMessage -To "CN=Max White" -out .\process.enc

Правильное декодирование зашифрованных данных при использовании UTF-8 В этом варианте вы можете воспользоваться соответствующими функциями Get-Content.

5.5 Аудит ключей PowerShell в реестре Реестр Windows содержит множество важных для безопасности параметров, которыми злоумышленник может манипулировать, чтобы обойти важные механизмы защиты. Например, злоумышленник может использовать его для обхода групповых политик. Аудит реестра помогает выявить такие нежелательные действия. Если вы хотите защитить PowerShell от неправомерного использования и записывать все команды, выполняемые из командной строки, в файл журнала, хакер, вероятно, захочет отключить эту функцию, чтобы не оставлять следов. Для этого он мог установить значение EnableTranscripting в 0. Этот ключ находится под: HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription Чтобы узнать о подобных манипуляциях, следует следить за соответствующими ключами в реестре. В нашем примере это будут те, которые устанавливаются объектами групповой политики (GPO) для PowerShell. Как и в случае с аудитом файловой системы, требуются три меры:  Включить мониторинг реестра через GPO  Настройте системный список управления доступом (SACL) для рассматриваемого ресурса.  Проанализируйте журнал событий

5.5.1 Активация аудита реестра Первый шаг — создать объект групповой политики и связать его с организационной единицей (OU), компьютеры которой вы хотите отслеживать на наличие изменений в ключах PowerShell в реестре. Затем откройте новую политику в редакторе GPO и перейдите в раздел Конфигурация компьютера => Политики => Параметры Windows => Параметры безопасности => Конфигурация расширенной политики аудита => Политики аудита => Доступ к объектам. (Microsoft устарела с параметрами в разделе «Параметры безопасности» => «Локальные политики» => «Политика аудита», начиная с Windows 7.)

Активировать аудит для регистрации через GPO Там вы активируете параметр «Аудит реестра», где вы видите два варианта: «Успех» и «Отказ». Решение о том, хотите ли вы записывать неудачные, успешные или оба доступа, зависит от типа и важности ресурса. Однако вы должны найти баланс между актуальностью записанных событий и объемом генерируемых данных. В нашем примере мы ограничиваемся только Success, чтобы узнать, когда действительно изменилось значение ключа. Выполнение этой команды на целевых компьютерах активирует групповую политику: gpupdate /force И теперь вы можете настроить SACL для ключа реестра.

5.5.2 Установка разрешений для разделов реестра Для этого перейдите в regedit.exe в указанную позицию в кусте реестра и выполните команду Permissions из контекстного меню ключа PowerShell. В следующем диалоговом окне нажмите «Дополнительно» и откройте вкладку «Проверка правок» в следующем диалоговом окне.

Редактирование SACL для ключей реестра в PowerShell Здесь вы добавляете новую запись. Сначала выберите принцип безопасности для отслеживания, например Все. На следующем шаге определите, какие действия следует записывать. Для нашей цели мы выбираем Query Value, Set Value и Delete, чтобы записать, что значение для этого ключа изменилось.

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

5.5.3 Настройка SACL через GPO При изменении SACL этого ключа в реестре многих компьютеров имеет смысл использовать GPO. Вы можете настроить необходимые параметры в разделе Конфигурация компьютера => Политики => Параметры Windows => Параметры безопасности => Реестр. Там вы открываете контекстное меню контейнера или щелкаете правой кнопкой мыши на правой панели. Затем выполните команду «Добавить ключ». В следующем диалоговом окне перемещайтесь по реестру, пока не найдете нужный ключ. Если этот ключ не существует на локальном компьютере, вы также можете ввести путь в поле ввода.

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

5.5.4 Оценка журнала событий Наконец, вы должны отслеживать записи в журнале событий, чтобы обнаруживать подозрительные действия. Найдите их в протоколе безопасности с идентификаторами 4656, 4657, 4660 и 4663. Поскольку нас интересуют только изменения в этом конкретном случае, идентификаторов событий 4657 и 4660 достаточно. ID 4660 представляет собой удаление. Вы можете получить эти журналы с помощью PowerShell следующим образом: Get-EventLog -LogName Security -Source "*auditing*" -InstanceId 4657,4660

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

Настройте настраиваемое представление в средстве просмотра событий, чтобы отфильтровать журналы аудита для регистрации. В качестве фильтра выберите «Безопасность» в разделе «Журналы событий», «Аудит безопасности Microsoft Windows» для «По источнику» и «Реестр» для категории «Задача». Кроме того, вы, конечно, также можете отфильтровать представление, используя идентификаторы событий.

6 Улучшить код PowerShell 6.1 Как избежать ошибок при использовании строгого режима Как и другие языки динамического программирования, PowerShell предоставляет пользователю большую свободу. Это упрощает быструю разработку коротких сценариев, но также способствует небрежному стилю программирования и всем вытекающим из этого проблемам. Строгий режим устраняет некоторые типичные ловушки PowerShell. Строгий режим не является функцией безопасности в узком смысле, хотя его можно использовать для предотвращения ошибок, которые в худшем случае могут привести к потере данных. Его основная цель

— предотвратить ошибки в синтаксически правильном коде, который приводит к нежелательным результатам. Их причины часто очень трудно отследить.

6.1.1 Версии строгого режима Perl уже давно знает такой механизм, и в VBScript вы можете использовать Option Explicit для принудительного объявления переменных перед их первым использованием. Однако этот механизм не слишком ограничивает разработчиков и не требует от них, например, объявления типов данных. В то время как в Perl вы можете включить строгий режим отдельно для переменных, подпрограмм и ссылок, PowerShell ожидает только номер версии или значение Off. Вы передаете номер версии командлету Set-StrictMode.

6.1.2 Строгий режим 1.0 Версия 1.0 запрещает использование необъявленных переменных: Set-StrictMode -Version 1.0 if( $a -gt 5 ){ Out-Host '$a is greater than 5' }

Строгий режим 1.0 предотвращает использование необъявленных переменных. Поскольку $a используется в выражении if без присвоенного ему значения, PowerShell показывает сообщение об ошибке в этот момент.

6.1.3 Строгий режим 2.0 Версия 2.0 дополнительно проверяет наличие ссылок на несуществующие свойства объекта. Это может произойти из-за опечатки или из-за того, что вы имеете дело с набором объектов, некоторые из которых не имеют определенных свойств. Например, если вы хотите отобразить все файлы, размер которых превышает определенный: Get-ChildItem | Where Length -gt 1GB

Когда активирован строгий режим версии 2.0, эта команда выдаст сообщение об ошибке для всех каталогов, поскольку они не имеют свойства длины.

Строгий режим 2.0 запрещает использование несуществующих свойств объекта. Здесь также становится очевидной амбивалентная природа этого режима, поскольку он вызывает тревогу даже в безобидных случаях. Без строгого режима каталоги просто не отображались бы. Вместо того, чтобы избегать строгого режима 2.0, в этом примере вам придется программировать более защищенно. Вы можете отфильтровать каталоги, используя свойство PSIsContainer: gci | ? {$_.PSIsContainer -eq $false -and $_.length -gt 1GB} Строгий режим 2.0 также помогает избежать неправильных вызовов функций. Различный синтаксис для выполнения методов и функций — одна из самых популярных ловушек в PowerShell, особенно для тех пользователей, которые часто имеют дело с другими языками программирования. Команда myfunc(1, 2, 3) интерпретирует аргументы как один массив вместо трех разных параметров.

6.1.4 Строгий режим 3.0 Наконец, существует версия 3.0 Strict Mode, но она не задокументирована. Вы получите его автоматически при вызове Set-StrictMode -Version Latest в PowerShell 3.0 или более поздней версии. Но вы также можете явно указать здесь «3.0». В дополнение к критериям двух других версий он также проверяет, не извлекаются ли элементы массива с недопустимым индексом. Это может произойти относительно легко, если вы перебираете элементы массива в цикле:

# At least PowerShell 3.0 $array = (1,2,3) # No error, output of $null Set-StrictMode -Version 2.0 for ($i= 0; $i -le 3; $i++){ $array[$i] } # Error IndexOutOfRangeException Set-StrictMode -Version 3.0 for ($i= 0; $i -le 3; $i++){ $array[$i] } Условием завершения цикла является $i -le 3 и это также будет ссылаться на $array[3]. Только с 3 элементами самый высокий индекс равен 2. Следовательно, строгий режим 3.0 также действует как средство проверки границ. Без него PowerShell вывел бы здесь значение $null.

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

Строгий режим, определенный в функции, не распространяется на вызовы в командной строке. Если вы установите строгий режим на версию 3.0 в функции, например, настройка по умолчанию останется на консоли, т.е. отключена. И наоборот, ввод Set-StrictMode -Version 3.0 в командной строке приведет к тому, что PowerShell проверит все сценарии, запущенные оттуда, чтобы увидеть, не выходит ли индекс массива за пределы.

6.2 Проверка кода с помощью ScriptAnalyzer Проект с открытым исходным кодом PSScriptAnalyzer разрабатывает средство проверки кода, которое сравнивает код скрипта с предопределенными правилами. Они основаны на лучших практиках для PowerShell. Он может даже автоматически исправлять определенные отклонения. Первые версии средства проверки кода могли быть интегрированы в PowerShell_ISE в виде надстройки под названием Script Browser. Однако это больше не работает в PowerShell 5.x, и плагин был удален из PS Gallery. Вместо этого Анализатор теперь доступен через расширение PowerShell для Visual Studio Code и как отдельный модуль.

6.2.1 Установка через управление пакетами Если вы разрабатываете PowerShell-скрипты не в VSCode, а в ISE, как наверняка будет делать большинство админов, то можно запустить проверку кода из командной строки. Для этого вам нужно сначала установить модуль из PSGallery: Install-Module -Name PSScriptAnalyzer Как команда Get-Command -Module PSScriptAnalyzer показывает, модуль предоставляет три командлета:  Get-ScriptAnalyzerRule  Invoke-ScriptAnalyzer  Invoke-Formatter

6.2.2 Отображение правил Первый из этих командлетов используется для отображения доступных правил, с которыми сравнивается код скриптов. Если вы вызовете его без параметров, он покажет все 55 стандартных правил, включая их описания. Полезным параметром является Severity, который может использовать значения Error и Warning, чтобы ограничить список серьезными или менее серьезными проблемами: Get-ScriptAnalyzerRule -Severity Error Эта команда покажет только те правила, нарушение которых будет классифицироваться как ошибка. Вам нужен обзор набора правил, если вы хотите учитывать только определенные рекомендации или исключать другие во время проверки.

Просмотрите правила по умолчанию для ScriptAnalyzer с помощью Get-ScriptAnalyzerRule. В последних версиях добавлено несколько правил:  AvoidAssignmentToAutomaticVariable: это сделано для того, чтобы разработчики не могли присваивать значения автоматическим переменным, таким как $_.  PossibleIncorrectUsageOfRedirectionOperator: в основном предназначен для разработчиков, которые часто используют другие языки программирования, где > или < служат операторами сравнения для большего или меньшего. Вместо этого PowerShell использует -gt или -lt. Символы > и < зарезервированы для перенаправления.  PossibleIncorrectUsageOfAssignmentOperator: проверяет возможное неправильное использование оператора присваивания. Это может произойти, например, если разработчики Basic проверяют выражение на равенство.  AvoidTrailingWhiteSpace: правило предупреждает о пробелах в конце строки кода. Они могут стать проблемой, если в операторе возникают разрывы строк.

6.2.3 Проверка кода скрипта Фактическая проверка кода выполняется с помощью Invoke-ScriptAnalyzer. В большинстве случаев вы передаете командлету имя файла сценария, который хотите проверить: Invoke-ScriptAnalyzer -Path .\MyPSScript.ps1 Параметры IncludeRules и ExcludeRules можно использовать для явного включения или исключения определенных правил. Если вы указываете здесь несколько правил, то они должны быть разделены запятой. Простые предупреждения можно подавить, например, присвоив значение Error параметру Severity.

В этом примере ScriptAnalyzer предупреждает об использовании псевдонима в скрипте. В версии 1.17.1 появилась новая опция «Fix», которая может автоматически исправлять некоторые отклонения от часто используемых правил. Это относится, например, к использованию псевдонимов для командлетов. В некоторых случаях авторам скриптов приходится редактировать такие исправления вручную, например, при преобразовании обычного текста в защищенную строку. Если вы хотите проверить только фрагмент кода, а не весь файл скрипта, используйте параметр ScriptDefinition вместо Path и передайте ему код в качестве значения. В этом случае переключатель Fix недоступен по понятным причинам.

6.2.4 Скрипты форматирования Наконец, Invoke-Formatter — это третий командлет, поставляемый с модулем. Как следует из названия, авторы сценариев могут использовать его для очистки форматирования кода. Есть несколько соглашений на выбор, которые можно выбрать с помощью параметра «Настройки» с помощью автозаполнения.

Параметры форматирования Invoke-Formatter Он принимает код PowerShell только через параметр ScriptDefinition, поэтому вам, возможно, придется прочитать содержимое файла сценария через Get-Content-Raw, прежде чем передать его средству форматирования. Подробную документацию по модулю можно найти на Github (bit.ly/2rSLdil).