Windows и PowerShell имеют встроенные функции безопасности и конфигурации по умолчанию, предназначенные для предотвращения случайного запуска конечными пользователями сценариев в ходе их повседневной деятельности. Однако, если ваши ежедневные действия обычно включают в себя написание и запуск собственных сценариев PowerShell, это может быть скорее неприятностью, чем преимуществом. Здесь мы покажем вам, как обойти эти функции без полного ущерба для безопасности.
Как и почему Windows & PowerShell предотвращают выполнение скриптов.
PowerShell – это по сути командная оболочка и язык сценариев, предназначенный для замены CMD и пакетных сценариев в системах Windows. Таким образом, сценарий PowerShell может быть в значительной степени настроен на выполнение всего, что вы можете сделать вручную из командной строки. Это равносильно внесению практически любых изменений в вашу систему, вплоть до ограничений, установленных для вашей учетной записи пользователя. Так что, если бы вы могли просто дважды щелкнуть скрипт PowerShell и запустить его с полными привилегиями администратора, такая простая однострочная строка, как эта, могла бы действительно разрушить ваш день:
Get-ChildItem "$ env: SystemDrive \" -Recurse -ErrorAction SilentlyContinue | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
НЕ запускайте указанную выше команду!
Это просто проходит через файловую систему и удаляет все, что может. Интересно, что это может не сделать систему неработоспособной так быстро, как вы думаете – даже при запуске из сеанса с повышенными правами. Но если кто-то позвонит вам после запуска этого скрипта, потому что он вдруг не сможет найти свои файлы или запустить некоторые программы, «выключение и повторное включение», вероятно, просто приведет их в Windows Startup Repair, где им скажут, что есть ничего, что можно сделать, чтобы решить проблему. Что может быть хуже, вместо того, чтобы получить скрипт, который просто разрушает их файловую систему, ваш друг может быть обманут, запустив тот, который загружает и устанавливает кейлоггер или службу удаленного доступа. Тогда, вместо того, чтобы задавать вам вопросы о Startup Repair, они могут в конечном итоге задать полиции несколько вопросов о банковском мошенничестве!
К настоящему времени должно быть очевидно, почему необходимы определенные вещи, чтобы, так сказать, защитить конечных пользователей от самих себя. Но опытные пользователи, системные администраторы и другие вундеркинды, как правило (хотя и есть исключения), немного более осторожны с этими угрозами, зная, как их легко обнаружить и легко избежать, и просто хотят продолжить работу. Для этого им придется либо отключить, либо обойти несколько дорожных блоков:
-
PowerShell не разрешает выполнение внешних скриптов по умолчанию.
Параметр ExecutionPolicy в PowerShell запрещает выполнение внешних сценариев по умолчанию во всех версиях Windows. В некоторых версиях Windows по умолчанию вообще не разрешено выполнение скрипта. Мы показали вам, как изменить этот параметр в разделе Как разрешить выполнение сценариев PowerShell в Windows 7, но здесь мы также рассмотрим его на нескольких уровнях. -
PowerShell по умолчанию не связан с расширением файла .PS1.
Мы впервые затронули эту тему в нашей серии PowerShell Geek School. Windows устанавливает действие по умолчанию для файлов .PS1, чтобы открыть их в блокноте, а не отправлять их в интерпретатор команд PowerShell. Это делается для того, чтобы напрямую предотвратить случайное выполнение вредоносных скриптов, когда они просто дважды щелкаются мышью. -
Некоторые сценарии PowerShell не будут работать без прав администратора.
Даже если вы работаете с учетной записью уровня администратора, вам все равно нужно пройти контроль учетных записей (UAC) для выполнения определенных действий. Для инструментов командной строки это может быть немного громоздко, если не сказать больше. Мы не хотим отключать UAC, но по-прежнему приятно, когда с ним немного легче иметь дело.
Эти же проблемы описаны в разделе Как использовать пакетный файл для упрощения запуска сценариев PowerShell, где мы расскажем, как написать пакетный файл, чтобы временно обойти их. Теперь мы покажем вам, как настроить вашу систему с помощью более долгосрочного решения. Имейте в виду, что обычно вы не должны вносить эти изменения в системы, которые не используются исключительно вами, иначе вы подвергаете других пользователей более высокому риску столкнуться с теми же проблемами, которые эти функции предназначены для предотвращения.
Изменение ассоциации файлов .PS1.
Первое, и, возможно, самое главное, раздражение, которое нужно обойти, – это ассоциация по умолчанию для файлов .PS1. Связывание этих файлов с чем-либо кроме PowerShell.exe имеет смысл для предотвращения случайного выполнения нежелательных сценариев. Но, учитывая, что PowerShell поставляется с интегрированной средой сценариев (ISE), которая специально разработана для редактирования сценариев PowerShell, почему мы хотим открывать файлы .PS1 в Блокноте по умолчанию?Даже если вы не готовы полностью переключиться на включение функции двойного щелчка, вы, вероятно, захотите изменить эти настройки.
Вы можете изменить привязку файла .PS1 к любой программе, которую вы хотите, с помощью панели управления «Программы по умолчанию», но копание непосредственно в реестр даст вам немного больше контроля над тем, как именно будут открываться файлы. Это также позволяет вам устанавливать или изменять дополнительные параметры, которые доступны в контекстном меню для файлов .PS1. Не забудьте сделать резервную копию реестра, прежде чем сделать это!
Параметры реестра, управляющие открытием скриптов PowerShell, хранятся в следующем месте:
HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell
Чтобы изучить эти настройки перед тем, как приступить к их изменению, посмотрите на этот ключ и его подключи с помощью Regedit. Ключ Shell должен иметь только одно значение «(по умолчанию)», для которого установлено значение «Открыть». Это указатель на действие по умолчанию для двойного щелчка по файлу, который мы увидим в подразделах.
Разверните ключ Shell, и вы увидите три подраздела. Каждый из них представляет действие, которое вы можете выполнить, специфичное для сценариев PowerShell.
Вы можете расширить каждый ключ, чтобы изучить значения внутри, но они в основном соответствуют следующим значениям по умолчанию:
- 0 – запустить с PowerShell. «Запускать с PowerShell» – это название опции, которая уже есть в контекстном меню для сценариев PowerShell. Текст просто извлекается из другого места вместо использования имени ключа, как другие. И это все еще не действие двойного щелчка по умолчанию.
- Редактировать – Открыть в PowerShell ISE. Это имеет гораздо больший смысл, чем Блокнот, но вам все равно нужно щелкнуть правой кнопкой мыши файл .PS1, чтобы сделать это по умолчанию.
- Открыть – открыть в блокноте. Обратите внимание, что это имя ключа также является строкой, хранящейся в значении «(по умолчанию)» ключа Shell. Это означает, что двойной щелчок по файлу откроет его, и это действие обычно настроено на использование Блокнота.
Если вы хотите придерживаться предварительно созданных командных строк, которые уже доступны, вы можете просто изменить значение «(По умолчанию)» в ключе оболочки, чтобы оно совпадало с именем ключа, которое соответствует тому, что вы хотите сделать двойным щелчком мыши. Это можно легко сделать из Regedit, или вы можете использовать уроки, извлеченные из нашего руководства по изучению реестра с помощью PowerShell (плюс небольшую настройку PSDrive), чтобы начать создавать повторно используемый скрипт, который может настраивать ваши системы для вас. Приведенные ниже команды должны запускаться из сеанса PowerShell с повышенными правами, аналогично запуску CMD в качестве администратора.
Во-первых, вы захотите настроить PSDrive для HKEY_CLASSES_ROOT, так как он не настроен по умолчанию. Команда для этого:
Новый реестр PSK-накопителей HKCR HKEY_CLASSES_ROOT
Теперь вы можете перемещаться и редактировать ключи реестра и значения в HKEY_CLASSES_ROOT так же, как и в обычных PSDrive HKCU и HKLM.
Чтобы настроить двойной щелчок для запуска сценариев PowerShell напрямую:
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell '(по умолчанию)' 0
Чтобы настроить двойной щелчок для открытия сценариев PowerShell в PowerShell ISE:
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell '(по умолчанию)' 'Изменить'
Чтобы восстановить значение по умолчанию (устанавливает двойной щелчок, чтобы открыть сценарии PowerShell в Блокноте):
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell '(по умолчанию)' 'Открыть'
Это просто основы изменения действия двойного щелчка по умолчанию. В следующем разделе мы подробнее рассмотрим настройку обработки сценариев PowerShell при их открытии в PowerShell из Проводника. Имейте в виду, что область действия не позволяет PSDrive сохраняться в течение сеанса. Итак, вы, вероятно, захотите включить строку New-PSDrive в начале любого скрипта конфигурации, который вы создаете для этой цели, или добавить его в свой профиль PowerShell. В противном случае вам нужно будет запустить этот бит вручную, прежде чем пытаться внести изменения таким образом.
Изменение параметра PowerShell ExecutionPolicy.
ExecutionPolicy в PowerShell – это еще один уровень защиты от выполнения вредоносных сценариев. Есть несколько вариантов для этого, и несколько различных способов его установки. Доступны следующие варианты: от большинства до наименее безопасных:
- Restricted – Сценарии не разрешены для запуска. (Настройка по умолчанию для большинства систем.) Это даже предотвратит запуск скрипта вашего профиля.
- AllSigned – все сценарии должны иметь цифровую подпись доверенного издателя для запуска без запроса пользователя. Скрипты, подписанные издателями, которые явно определены как ненадежные, или сценарии, не имеющие цифровой подписи, не будут выполняться. PowerShell запросит у пользователя подтверждение, если скрипт подписан издателем, еще не определенным как доверенный или недоверенный. Если вы не подписали скрипт профиля в цифровой форме и не установили доверие к этой подписи, он не сможет работать.Будьте осторожны с издателями, которым вы доверяете, так как вы все равно можете запустить вредоносные скрипты, если доверяете не тем.
- RemoteSigned – для сценариев, загружаемых из Интернета, это фактически то же самое, что «AllSigned». Однако сценарии, созданные локально или импортированные из источников, отличных от Интернета, могут запускаться без запроса подтверждения. Здесь вы также должны быть осторожны с цифровыми подписями, которым вы доверяете, и даже быть осторожнее с неподписанными сценариями, которые вы выбираете для запуска. Это самый высокий уровень безопасности, при котором вы можете иметь скрипт рабочего профиля без необходимости его цифровой подписи.
- Неограниченно – все сценарии разрешено запускать, но для сценариев из Интернета потребуется запрос подтверждения. Начиная с этого момента, вы должны избегать запуска ненадежных сценариев.
- Обход – все работает без предупреждения. Будьте осторожны с этим.
- Не определено – политика не определена в текущей области. Это используется для обеспечения возврата к политикам, определенным в более низких областях (более подробно ниже), или к настройкам по умолчанию ОС.
Как следует из описания Undefined, вышеуказанные политики могут быть установлены в одной или нескольких из нескольких областей. Вы можете использовать Get-ExecutionPolicy с параметром -List, чтобы увидеть все области и их текущую конфигурацию.
Области действия перечислены в порядке приоритета, при этом верхняя определенная область действия переопределяет все остальные. Если политики не определены, система возвращается к настройкам по умолчанию (в большинстве случаев это ограничение).
- MachinePolicy представляет групповую политику, действующую на уровне компьютера. Обычно это применяется только в домене, но может быть сделано и локально.
- UserPolicy представляет групповую политику, действующую на пользователя. Это также обычно используется только в корпоративных средах.
- Процесс – это область, специфичная для этого экземпляра PowerShell. Изменения в политике в этой области не затронут другие запущенные процессы PowerShell и будут неэффективными после завершения этого сеанса. Это можно настроить с помощью параметра -ExecutionPolicy при запуске PowerShell или с помощью правильного синтаксиса Set-ExecutionPolicy изнутри сеанса.
- CurrentUser – это область, которая настраивается в локальном реестре и применяется к учетной записи пользователя, используемой для запуска PowerShell. Эту область можно изменить с помощью Set-ExecutionPolicy.
- LocalMachine – это область, настроенная в локальном реестре и применяемая ко всем пользователям в системе. Это область по умолчанию, которая изменяется, если Set-ExecutionPolicy запускается без параметра -Scope. Поскольку он применяется ко всем пользователям в системе, его можно изменить только из сеанса с повышенными правами.
Поскольку эта статья в основном посвящена обходу безопасности и упрощению юзабилити, мы просто обеспокоены тремя нижними областями. Настройки MachinePolicy и UserPolicy действительно полезны, только если вы хотите применить ограничительную политику, которую так просто не обойти. Сохраняя наши изменения на уровне Процесса или ниже, мы можем легко использовать любой параметр политики, который мы считаем подходящим для данной ситуации, в любое время.
Чтобы сохранить некоторый баланс между безопасностью и удобством использования, политика, показанная на скриншоте, вероятно, является лучшей. Если для политики LocalMachine установлено значение Restricted, то, как правило, запрещается запускать скрипты кем-либо, кроме вас Конечно, это могут быть обойдены пользователями, которые знают, что они делают без особых усилий. Но это должно удерживать любых неопытных пользователей от случайного запуска чего-то катастрофического в PowerShell. Если для CurrentUser (то есть для вас) задано значение Unrestricted, вы можете вручную запускать сценарии из командной строки, как вам нравится, но при этом сохраняются напоминания о предосторожности для сценариев, загружаемых из Интернета. Настройка RemoteSigned на уровне процесса должна быть выполнена в ярлыке PowerShell.exe или (как мы это сделаем ниже) в значениях реестра, которые управляют поведением сценариев PowerShell. Это обеспечит простую функциональность двойного щелчка для запуска любых сценариев, которые вы пишете, одновременно создавая более сильный барьер против непреднамеренного выполнения (потенциально вредоносных) сценариев из внешних источников. Мы хотим сделать это здесь, так как гораздо проще случайно дважды щелкнуть скрипт, чем обычно вызывать его вручную из интерактивного сеанса.
Чтобы установить политики CurrentUser и LocalMachine, как показано на снимке экрана выше, выполните следующие команды из сеанса PowerShell с повышенными правами:
Set-ExecutionPolicy Restricted Set-ExecutionPolicy Unrestricted -Scope CurrentUser
Чтобы применить политику RemoteSigned для сценариев, запускаемых из Проводника, нам нужно изменить значение в одном из ключей реестра, которые мы рассматривали ранее.Это особенно важно, поскольку в зависимости от версии PowerShell или Windows конфигурация по умолчанию может обойти все параметры ExecutionPolicy, кроме AllSigned. Чтобы увидеть текущую конфигурацию вашего компьютера, вы можете запустить эту команду (убедившись, что сначала HKCR PSDrive сопоставлен):
Get-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Command | Select-Object '(по умолчанию)'
Ваша конфигурация по умолчанию, вероятно, будет одной из следующих двух строк или чем-то похожим:
(Рассматривается в Windows 7 SP1 x64 с PowerShell 2.0)
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-file" "% 1"
(При использовании Windows 8.1 x64 с PowerShell 4.0)
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-Command" "if ((Get-ExecutionPolicy) -ne 'AllSigned') {Set-ExecutionPolicy -Scope Обход процесса}; & '% 1' "
Первый не так уж и плох, так как все, что он делает, – это запускает скрипт в существующих настройках ExecutionPolicy. Этого можно было бы улучшить, введя более жесткие ограничения для более подверженных авариям действий, но изначально это не было предназначено для запуска по двойному щелчку, а политика по умолчанию обычно все-таки ограничена. Второй вариант, однако, – это полный обход того, что ExecutionPolicy может иметь место, даже ограниченного. Поскольку обход будет применяться в области «Процесс», он влияет только на сеансы, которые запускаются при запуске сценариев из Проводника. Однако это означает, что вы можете в конечном итоге запускать сценарии, которые в противном случае вы могли бы ожидать (и хотели бы), чтобы ваша политика запрещала.
Чтобы установить уровень выполнения ExecutionPolicy для сценариев, запускаемых из Explorer, в соответствии с приведенным выше снимком экрана, вам нужно изменить то же значение реестра, которое мы только что запросили. Вы можете сделать это вручную в Regedit, изменив его на следующее:
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-ExecutionPolicy" "RemoteSigned" "-file" "% 1"
Вы также можете изменить настройку из PowerShell, если хотите. Не забудьте сделать это из сеанса с повышенными правами, с отображением HKCR PSDrive.
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Command '(по умолчанию)' 'C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe "" -ExecutionPolicy "" RemoteSigned "" -file ""% 1 "'
Запустите сценарии PowerShell от имени администратора.
Как плохая идея полностью отключить UAC, так и плохая практика безопасности – запускать скрипты или программы с повышенными привилегиями, если только они вам не нужны для выполнения операций, требующих доступа администратора. Поэтому не рекомендуется включать приглашение UAC в действие по умолчанию для сценариев PowerShell. Однако мы можем добавить новую опцию контекстного меню, чтобы позволить нам легко запускать сценарии в сеансах с повышенными правами, когда это необходимо. Это похоже на метод, используемый для добавления «Открыть с помощью блокнота» в контекстное меню всех файлов, но здесь мы собираемся использовать только сценарии PowerShell. Мы также собираемся продолжить некоторые методы, использованные в предыдущей статье, где мы использовали пакетный файл вместо взломов реестра для запуска нашего сценария PowerShell.
Чтобы сделать это в Regedit, вернитесь в ключ Shell по адресу:
HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell
Там создайте новый подраздел. Назовите это «Запуск с PowerShell (Admin)». Под этим создайте еще один подраздел под названием «Команда». Затем установите значение «(по умолчанию)» в разделе «Command» следующим образом:
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-Command" "" & {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy RemoteSigned -File \ "% 1 \"' -Verb RunAs} "
В этот раз для PowerShell потребуется три строки. Один для каждого нового ключа и один для установки значения «(по умолчанию)» для команды. Не забудьте высоту и отображение HKCR.
Новый элемент 'HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Run with PowerShell (Admin)' Новый элемент 'HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Запуск с PowerShell (Admin) \ Command' Set-ItemProperty 'HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Запускать с PowerShell (Admin) \ Command' '(по умолчанию)' '"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "- Команда "" "& {Start-Process PowerShell.exe -ArgumentList '' -ExecutionPolicy RemoteSigned -File \"% 1 \ "'' -Verb RunAs}" '
Кроме того, обратите особое внимание на различия между строкой, вводимой через PowerShell, и фактическим значением, которое вводится в Реестр. В частности, нам нужно обернуть все это в одинарные кавычки и удвоить внутренние одинарные кавычки, чтобы избежать ошибок при разборе команд.
Теперь у вас должна появиться новая запись контекстного меню для сценариев PowerShell, которая называется «Запускать с PowerShell (Admin)».
Новая опция порождает два последовательных экземпляра PowerShell.Первый – это просто средство запуска для второго, которое использует Start-Process с параметром «-Verb RunAs», чтобы запросить повышение прав для нового сеанса. Оттуда ваш сценарий должен быть в состоянии работать с правами администратора после того, как вы нажмете на приглашение UAC.
Последние штрихи.
Есть еще пара настроек, которые могут сделать жизнь еще проще. С одной стороны, как насчет полного избавления от функции «Блокнот»? Просто скопируйте значение «(по умолчанию)» с клавиши «Command» в «Edit» (ниже) в то же место в «Open».
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell_ise.exe" "% 1"
Или вы можете использовать этот бит PowerShell (конечно, с Admin & HKCR):
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Open \ Command '(по умолчанию)' '"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell_ise.exe" "% 1"'
Еще одним небольшим раздражением является привычка консоли исчезать после завершения сценария. Когда это происходит, у нас нет никакой возможности проверить вывод сценария на наличие ошибок или другой полезной информации. Об этом можно позаботиться, поставив паузу в конце каждого из ваших сценариев, конечно. Кроме того, мы можем изменить значения «(по умолчанию)» для наших командных клавиш, чтобы включить параметр «-NoExit». Ниже приведены измененные значения.
(Без доступа администратора)
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-NoExit" "-ExecutionPolicy" "RemoteSigned" "-file" "% 1"
(С правами администратора)
"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-Command" "" & {Start-Process PowerShell.exe -ArgumentList '-NoExit -ExecutionPolicy RemoteSigned -File \ "% 1 \ \ "'-Verb RunAs}"
И, конечно же, мы дадим вам те же команды PowerShell. Последнее напоминание: Высота & HKCR!
(Non-Admin)
Set-ItemProperty HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Command '(по умолчанию)' '' C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe "" -NoExit "" -ExecutionPolicy " "RemoteSigned" "-file" "% 1" '
(Admin)
Set-ItemProperty 'HKCR: \ Microsoft.PowerShellScript.1 \ Shell \ Запускать с PowerShell (Admin) \ Command' '(по умолчанию)' '"C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ powershell.exe "" -Command "" "& {Start-Process PowerShell.exe -ArgumentList '' -NoExit -ExecutionPolicy RemoteSigned -File \"% 1 \ "'' -Verb RunAs}" '
Принимая это за спин.
Чтобы проверить это, мы собираемся использовать сценарий, который может показать нам настройки ExecutionPolicy и определить, был ли сценарий запущен с разрешениями администратора. Сценарий будет называться «MyScript.ps1» и будет храниться в «D: \ Script Lab» в нашем примере системы. Код ниже, для справки.
if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()). IsInRole ([Security.Principal.WindowsBuiltInRole] «Администратор»)) {Write-Output 'Запуск от имени администратора!'} еще {Write-Output 'Running Limited!'} Get-ExecutionPolicy -List
Используя действие «Запуск с PowerShell»:
Используя действие «Запуск с PowerShell (Admin)», после нажатия через UAC:
Чтобы продемонстрировать ExecutionPolicy в действии в области «Процесс», мы можем заставить Windows думать, что файл был получен из Интернета с помощью следующего фрагмента кода PowerShell:
Add-Content -Path 'D: \ Script Lab \ MyScript.ps1' -Value "[ZoneTransfer]` nZoneId = 3 "-Stream 'Zone.Identifier'
К счастью, мы включили -NoExit. В противном случае эта ошибка просто моргнула бы, и мы бы не узнали!
Zone.Identifier может быть удален с этим:
Clear-Content -Path 'D: \ Script Lab \ MyScript.ps1' -Stream 'Zone.Identifier'
Полезные ссылки:
- Запуск сценариев PowerShell из командного файла – Блог программиста Дэниела Шредера
- Проверка прав администратора в PowerShell – Привет, сценарист! Блог