Добавить в корзинуПозвонить
Найти в Дзене
ТЕХНО 89

🛡️ Constrained Language Mode в PowerShell: мой личный гид от школьника до продвинутого DevOps

Привет, коллеги. Хочу поделиться опытом, который накопился за годы настройки безопасности в корпоративных средах. Если коротко: скриптовые атаки через PowerShell — это не теория, это ежедневная реальность. По данным отчётов 2024–2025 годов, более 70% инцидентов с использованием техник Living-off-the-Land начинаются именно с PowerShell. И знаете, что меня удивляет? Многие админы до сих пор помечают настройку Constrained Language Mode (CLM) как риск: средний и откладывают её внедрение. Я сам так делал, пока не увидел, как один пропущенный скрипт стал точкой входа для целой цепочки атак. Мой вывод простой: CLM — это не галочка для аудита. Это реальный инструмент, который отсекает 60–80% опасных возможностей языка, оставляя работоспособными 90% штатных задач. Ниже — мой личный разбор: как включить, что сломается, как починить, и как встроить это в современные практики без боли. Давайте без воды. Constrained Language Mode — это режим, в котором PowerShell работает как в «песочнице». Он не з
Оглавление

Привет, коллеги. Хочу поделиться опытом, который накопился за годы настройки безопасности в корпоративных средах. Если коротко: скриптовые атаки через PowerShell — это не теория, это ежедневная реальность. По данным отчётов 2024–2025 годов, более 70% инцидентов с использованием техник Living-off-the-Land начинаются именно с PowerShell.

И знаете, что меня удивляет? Многие админы до сих пор помечают настройку Constrained Language Mode (CLM) как риск: средний и откладывают её внедрение. Я сам так делал, пока не увидел, как один пропущенный скрипт стал точкой входа для целой цепочки атак.

Мой вывод простой: CLM — это не галочка для аудита. Это реальный инструмент, который отсекает 60–80% опасных возможностей языка, оставляя работоспособными 90% штатных задач. Ниже — мой личный разбор: как включить, что сломается, как починить, и как встроить это в современные практики без боли.

🔍 Что такое CLM на самом деле

Давайте без воды. Constrained Language Mode — это режим, в котором PowerShell работает как в «песочнице». Он не запрещает скрипты вообще, но физически не даёт выполнять опасные операции на уровне движка.

Вот что я обычно объясняю новичкам:
• Если скрипт пытается загрузить случайный .NET-тип через Add-Type — CLM скажет
нет
• Если код использует рефлексию или COM-объекты — доступ заблокирован
• Если кто-то пытается обойти защиту через in-memory инъекции — AMSI + CLM остановят это

А что остаётся? Всё, что нужно для повседневной работы: базовые cmdlet, работа с файлами, реестром, сетью, утверждённые модули.

Проверить режим проще простого — одна команда:

$ExecutionContext.SessionState.LanguageMode

Увидели ConstrainedLanguage? Значит, защита работает. Если FullLanguage — самое время задуматься.

🛠️ Как включить: инструкция, с которой справится даже школьник

Я специально пишу этот раздел так, чтобы его понял любой. Без жаргона, без предположений.

Шаг 1. Открываем редактор политик
Нажмите Win + R, введите gpedit.msc, нажмите Enter.
Важно: в Windows 10/11 Home этого редактора нет по умолчанию. Для домашних версий переходите сразу к Шагу 4.

Шаг 2. Ищем нужный параметр
Переходим по пути:
Конфигурация компьютера → Административные шаблоны → Компоненты Windows → Windows PowerShell

Шаг 3. Включаем защиту
Находим политику
Включить режим ограниченного языка, дважды кликаем, выбираем Включено → Применить → ОК.

Шаг 4. Проверяем результат
Откройте PowerShell
от обычного пользователя и введите:

$ExecutionContext.SessionState.LanguageMode

Если видите ConstrainedLanguage — поздравляю, вы справились. Если нет — закройте все окна терминала и откройте заново. Политика применяется только к новым сессиям.

🔹 Для Windows Home или быстрых тестов
Запустите PowerShell от имени администратора и выполните:

[Environment]::SetEnvironmentVariable("__PSLockdownPolicy", "4", "Machine")

Перезапустите терминал. Готово. Для отката замените 4 на 0.

Личный лайфхак: перед массовым внедрением протестируйте на виртуалке. Это сэкономит нервы и время.

✅ ПОДПИСКА, ❤️ ЛАЙК, 🔄 РЕПОСТ друзьям, 💰 ДОНАТ на сбер по QR 👇
📌 2200 2803 3202 5362 💯 МТС-Банк *** СПАСИБО за Вашу поддержку ***
-2

💰ПОДДЕРЖКА АВТОРА - ДЕЛО ДОБРОЙ ВОЛИ💰

-3

⚠️ Пять типичных проблем и как я их решаю

Когда я впервые включал CLM в продакшене, думал: «всё сломается». Реальность оказалась проще — но только если знать, что ждать. Делюсь своим чек-листом.

🔸 Проблема 1: скрипты с Add-Type перестали работать
Почему: CLM блокирует динамическую компиляцию .NET в памяти.

Моё решение: выношу код в отдельную DLL, подписываю сертификатом, добавляю в AppLocker как доверенный. Если нужно быстро — использую __PSLockdownPolicy=0 только для конкретного сервисного аккаунта через GPO Preferences.

🔸 Проблема 2: SCCM, Exchange Shell или дашборды «потеряли» функции
Почему: легаси-утилиты часто используют COM или рефлексию.

Моё решение: создаю исключения в AppLocker по хэшу или пути. Да, CLM включается автоматически при Enforcement, но вы можете точечно разрешить нужным .exe работать в полном режиме.

🔸 Проблема 3: CI/CD пайплайны падают на этапе сборки
Почему: build-агенты используют PowerShell для упаковки и деплоя.

Моё решение: изолирую среду. Использую отдельные пулы агентов или ephemeral-контейнеры, где для build-аккаунтов явно отключаю CLM. Никогда не применяю глобальный CLM к сборочным серверам — это правило, которое я вывел на своих ошибках.

🔸 Проблема 4: IntelliSense в VS Code ведёт себя странно
Почему: расширение пытается загрузить метаданные через ограниченные API.

Моё решение: обновляю расширение до последней версии. В настройках VS Code добавляю:
"powershell.integratedConsole.languageMode": "Constrained"
Или работаю через Remote-SSH / Dev Containers — там изоляция уже «из коробки».

🔸 Проблема 5: политика не применяется на отдельных хостах
Почему: конфликт политик, медленная репликация AD, блокировка антивирусом.

Моё решение: выполняю gpupdate /force, проверяю журнал Microsoft-Windows-GroupPolicy/Operational, убеждаюсь, что хост в нужном OU. Если мешает AV — добавляю gpsvc.exe и svchost.exe (PolicyAgent) в исключения сканирования.

💻 Что я рекомендую разработчикам и DevOps-инженерам

Если вы пишете код или управляете инфраструктурой, CLM — не враг, а союзник. Вот как я встраиваю его в рабочие процессы.

IaC и провижининг
Terraform сам по себе не использует PowerShell для основной логики, но local-exec/remote-exec могут. Я всегда проверяю, в каком контексте выполняются команды. Для Ansible указываю ansible_shell_type: cmd или явно задаю путь к pwsh с предварительной проверкой режима.

Контейнеризация
В официальных образах mcr.microsoft.com/powershell CLM выключен по умолчанию. Я добавляю в Dockerfile одну строку:

ENV __PSLockdownPolicy=4

Это гарантирует, что даже в ephemeral-средах образ соответствует принципу least privilege.

Тестирование до продакшена
Я пишу простой Pester-тест, который запускает скрипт в изолированном процессе:

It "Скрипт должен выполняться в CLM без ошибок" {
[Environment]::SetEnvironmentVariable("__PSLockdownPolicy", "4", "Process")
$result = & { .\MyScript.ps1 } 2>&1
$result | Should -Not -Match "LanguageMode"
}

Интегрирую в CI — и сплю спокойнее.

Секреты и переменные
Важно помнить: CLM не шифрует данные. Я комбинирую его с Windows DPAPI, Azure Key Vault или HashiCorp Vault. Никогда не хардкодлю пароли в скриптах — даже если они «безопасны» для CLM.

JEA или CLM? Что выбрать
JEA работает в Full Language Mode, но с ограниченным набором команд. Я использую JEA для делегирования админ-прав, а CLM — для пользовательских и фоновых задач. Это даёт точечный контроль без компромиссов.

PowerShell 7+ или 5.1?
CLM работает одинаково, но в PS7 некоторые модули требуют явного указания доверенных путей. Я обновляю PSModulePath, избегаю Import-Module -SkipEditionCheck без крайней нужды и всегда тестирую критические сценарии в обеих версиях.

📊 Мониторинг: как я не теряю контроль после включения

Включить CLM — это только начало. Без видимости вы слепы. Вот мой минимальный набор для контроля.

🔹 Script Block Logging
В том же разделе GPO включаю Turn on PowerShell Script Block Logging. Это записывает каждый выполненный блок кода — даже если он закодирован или обфусцирован.

🔹 Модульное логирование
Добавляю Turn on PowerShell Module Logging и указываю модули для отслеживания: Microsoft.PowerShell.*, ActiveDirectory, Exchange.

🔹 Анализ событий
Мониторю Event ID 4103 (выполнение блока), 4104 (завершение) и события смены контекста в журнале:
Applications and Services Logs → Microsoft → Windows → PowerShell → Operational

🔹 Zero Trust
В современных стеках (Intune, Entra ID, WDAC) CLM — базовое требование для уровней Managed Device и Secure Core. Без него хост может быть изолирован политиками Conditional Access.

🔹 Авто-откат и алертинг
Настраиваю скрипт входа, который проверяет $ExecutionContext.SessionState.LanguageMode. Если значение не совпадает с ожидаемым — автоматически применяется __PSLockdownPolicy=4 и уходит алерт в SIEM или мессенджер.

✅ Мой итог и приглашение к диалогу

Если резюмировать мой опыт: Constrained Language Mode — это не «ещё одна галочка». Это сдвиг мышления: от разрешить всё к разрешить только доказанное безопасным.

Я начинаю с пилотной группы из 5–10 хостов, включаю логирование, проверяю совместимость через AppLocker или переменные среды — и только потом масштабирую. Так я закрываю вектор LotL-атак до того, как он станет инцидентом.

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

#PowerShell #ConstrainedLanguageMode #CLM #InfoSec #CyberSecurity #DevOps #SRE #SysAdmin #WindowsSecurity #GPO #AppLocker #WDAC #ZeroTrust #Automation #Scripting #LotL #EDR #SIEM #ITInfrastructure #SysOps #PowerShellCore #Pester #DockerSecurity #CICD #ITAdmin #CyberDefense #WindowsAdmin #ScriptSecurity #TechGuide #SecureAutomation