
Кроссплатформенная интерактивная оболочка для Microsoft Defender for Endpoint Live Response
Кроссплатформенная интерактивная оболочка для Microsoft Defender for Endpoint Live Response.
| Функция | Описание |
|---|---|
| Платформа | PowerShell Core 7.0+ (Windows, Linux, macOS) |
| Режимы API | Внутренний (портал, почти реальное время) и Официальный (публичный, без состояния) |
| Выполнение | Произвольные команды + 25 встроенных команд LR |
| Аутентификация | 7 методов аутентификации, единое меню, автообновление |
| Лицензия | MIT |
LaraC2 Shell подключается к MDE Live Response через два независимых API-пути — внутренний API портала (постоянные сессии, задержка ~2-5 с) и официальный публичный API (на команду, задержка ~20-60 с). Он автоматически загружает заглушки исполнителей, прозрачно обрабатывает ограничение скорости и предоставляет полноценную REPL с управлением машинами, управлением библиотеками и встроенной справочной системой.
connect повторно аутентифицирует при истечении сессииmulti с фильтрацией по шаблону имени и ограничением top-NMachine.LiveResponse + Library.Manage (официальный режим)git clone https://github.com/akefallonitis/larac2shell.git cd larac2shell pwsh -File shell/Invoke-MDEShell.ps1
Вот и всё. Оболочка при первом запуске показывает единое меню аутентификации из 7 методов — выберите один, пройдите аутентификацию, выберите машину, и вы в REPL. Никакого конфигурационного файла, никаких флагов, ничего настраивать не нужно.```
Select API mode:
Internal API (security.microsoft.com — near real-time, ~2-5s/cmd)
1 Credentials + MFA username + password, TOTP/push/SMS [auto-refresh]
2 Software passkey FIDO2/WebAuthn JSON key file [auto-refresh]
3 ESTS cookie ESTSAUTHPERSISTENT from browser (~24hr)
4 Temporary Access Pass one-time admin-issued code
5 Direct sccauth + XSRF cookies from browser DevTools (~1hr)
Official API (api.securitycenter.microsoft.com — CI/CD ready, ~20-60s/cmd)
6 Device code browser login (interactive)
7 Client credentials app registration with client secret
Auth method (1-7):
Варианты 1-5 устанавливают внутренний режим, 6-7 — официальный. Вы можете переключать режимы позже без перезапуска — см. Переключение режимов в строке ниже.
[INT myhost C:]> mode Current mode: Internal API Switch with: 'mode internal' or 'mode official'.
[INT myhost C:]> mode official [Mode] Switching from Internal API to official... (auth menu for official mode opens) [Mode] Now in official mode. Run 'machines' to list targets or 'connect <name|id>' to select one.
`mode <target>` отсоединяет любой текущий сеанс LR, очищает старое состояние аутентификации и повторно запускает поток аутентификации для целевого режима. Когда он возвращается, вы аутентифицированы в новом режиме без выбранной машины — выполните `machines`, чтобы вывести список, или `connect <name|id>`, чтобы сразу перейти к цели. Перезагрузка не требуется.
### Ярлыки CLI (опционально)```powershell
# Pre-select the mode (narrows the auth menu to 1-5 or 6-7)
pwsh -File shell/Invoke-MDEShell.ps1 -Mode internal
pwsh -File shell/Invoke-MDEShell.ps1 -Mode official
# Pre-select a machine (skips the picker)
pwsh -File shell/Invoke-MDEShell.ps1 -Machine myhost
# Software passkey path (internal mode)
pwsh -File shell/Invoke-MDEShell.ps1 -PasskeyPath ./keys/passkey.json
# Non-interactive single command (exits with remote command's exit code)
pwsh -File shell/Invoke-MDEShell.ps1 -Machine myhost -Command 'whoami'
Используется только в одном сценарии: официальный режим с секретом клиента, неинтерактивно. Каждый другой метод аутентификации запрашивает данные интерактивно и ничего не сохраняет на диске. Если вам не нужна автоматическая аутентификация по клиентским учетным данным, этот раздел можно полностью пропустить.```powershell Copy-Item shell/config/shell-config.example.json shell/config/shell-config.json
pwsh -File shell/Invoke-MDEShell.ps1 -Config shell/config/shell-config.json
Схема конфигурации (все поля необязательны, кроме `official.tenantId` + `official.clientId` при использовании клиентских учетных данных):
| Раздел | Поле | Описание |
|---------|-------|-------------|
| `official` | `tenantId` | ID арендатора Azure AD |
| `official` | `clientId` | ID клиента регистрации приложения |
| `official` | `clientSecret` | Секрет клиента (опустите и установите `useDeviceCode: true` для кода устройства) |
| `official` | `useDeviceCode` | `true` для использования потока кода устройства вместо клиентских учетных данных |
| `defaults` | `defaultMachine` | Предварительно выбрать машину при запуске (подстрока имени или префикс ID) |
| `defaults` | `commandTimeoutSeconds` | Верхняя граница тайм-аута на стороне клиента. `0` = сервер решает (до 1800 с). |
| `defaults` | `pollIntervalOfficial` | Интервал опроса официального API в секундах (по умолчанию 2) |
| `defaults` | `pollIntervalInternal` | Интервал опроса внутреннего API в секундах (по умолчанию 1) |
**Безопасность**: Ограничьте права доступа к файловой системе на любом конфигурационном файле, содержащем `clientSecret`. `clientSecret` никогда не принимается в командной строке — только в конфигурационном файле. Все учетные данные внутреннего режима (имя пользователя, пароль, секрет TOTP, куки) запрашиваются интерактивно и никогда не сохраняются на диск.
---
## Методы аутентификации
Оболочка представляет единое меню аутентификации из 7 методов при запуске. Режим (внутренний/официальный) определяется на основе выбора.
| # | Режим | Метод | Как | Автообновление |
|---|------|--------|-----|--------------|
| 1 | Внутренний | Учетные данные + TOTP | Интерактивный запрос | Да (незаметно) — только когда был предоставлен секрет TOTP. При push/SMS MFA сессия не может обновляться автоматически. |
| 2 | Внутренний | Программный ключ доступа | Параметр `-PasskeyPath` или запрос | Да (незаметно) |
| 3 | Внутренний | Кука ESTS | Интерактивный запрос | Нет (~24 ч) |
| 4 | Внутренний | Временный ключ доступа | Интерактивный запрос | Нет (одноразовый) |
| 5 | Внутренний | Прямой sccauth + XSRF | Интерактивный запрос | Нет (~1 ч) — автоматическое обновление XSRF не применяется; оболочка не обновляет автоматически куки, предоставленные напрямую. |
| 6 | Официальный | Код устройства | Вход в браузере | Нет (~1 ч) |
| 7 | Официальный | Клиентские учетные данные | Конфигурационный файл | Да (незаметно) |
Команда `connect` повторно аутентифицируется при истечении сессии, используя тот же метод, который был выбран изначально. Методы без автообновления снова запрашивают интерактивный ввод.
**Обработка учетных данных в памяти**: для метода 1 предоставленный пароль и секрет TOTP сохраняются в памяти (как простые строки, внутри `$script:Int_ReauthParams`) на время жизни процесса оболочки, чтобы автоматическая повторная аутентификация могла выполняться без участия пользователя. Строковые объекты находятся в пространстве выполнения PowerShell; они не сериализуются на диск и не передаются через командную строку. Если такое раскрытие неприемлемо для вашей модели угроз, используйте метод 2 (ключ доступа/HSM) или метод 7 (клиентские учетные данные).
---
## Команды оболочки
### Управление оболочкой
| Команда | Описание |
|---------|-------------|
| `help [command]` | Показать справку (опционально для конкретной команды) |
| `help commands` | Вывести все встроенные команды LR с описаниями |
| `status` | Показать статус подключения, состояние аутентификации, информацию о машине |
| `config` | Показать конфигурацию Live Response |
| `connect [name\|id]` | Повторно аутентифицироваться (если истек срок) и выбрать машину |
| `disconnect` | Отключить текущую сессию LR и очистить машину |
| `multi [options] <cmd>` | Выполнить команду на нескольких машинах (`-top N`, `-filter pattern`) |
| `session [list]` | Показать информацию о текущей сессии или все кэшированные сессии |
| `mode` | Показать текущий режим API |
| `mode internal\|official` | Переключить режим API на месте — отключает текущую сессию, удаляет старое состояние аутентификации и запускает меню аутентификации для целевого режима. После этого можно продолжить с `machines` или `connect` |
| `exit` / `quit` / `q` | Выйти из оболочки |
### Управление машинами
| Команда | Описание |
|---------|-------------|
| `machines [refresh]` | Вывести список машин и выбрать одну (refresh = принудительная перезагрузка) |
| `connect [name\|id]` | Подключиться к машине по подстроке имени или префиксу ID |
### Встроенные команды Live Response (всего 25)
| Команда | Описание |
|---------|-------------|
| `run <script> [args]` | Выполнить скрипт из библиотеки MDE |
| `getfile <path>` | Скачать файл с удаленной машины |
| `putfile <name>` | Загрузить файл из библиотеки в удаленную рабочую директорию |
| `processes` | Вывести запущенные процессы |
| `connections` | Вывести активные сетевые подключения |
| `cd <path>` | Изменить рабочую директорию (внутренний режим) |
| `dir [path]` | Вывести содержимое директории |
| `findfile <name>` | Искать файл по имени на всех дисках |
| `trace` | Показать диагностическую трассировку |
| `analyze <path>` | Отправить файл на углубленный анализ |
| `remediate <path>` | Поместить в карантин/исправить файл |
| `undo <actionId>` | Отменить предыдущее действие по исправлению |
| `registry <key>` | Запросить ключи/значения реестра (только Windows) |
| `scheduledtasks` | Вывести запланированные задачи |
| `persistence` | Проверить распространенные места персистентности |
| `drivers` | Вывести загруженные драйверы (только Windows) |
| `services` | Вывести службы |
| `startupfolders` | Вывести содержимое папок автозагрузки (только Windows) |
| `fileinfo <path>` | Получить подробную информацию о файле |
| `prefetch` | Вывести данные prefetch (только Windows) |
| `log` | Просмотреть диагностические журналы |
| `jobs` | Вывести фоновые задания (внутренний режим) |
| `fg <jobId>` | Перевести фоновое задание на передний план (внутренний режим) |
| `library` | Управлять файлами библиотеки (список, загрузка, скачивание, удаление) |
| `status` | Показать статус сессии и диагностику |
### Псевдонимы команд
| Псевдоним | Разрешается в |
|-------|-------------|
| `ls` | `dir` |
| `ps` | `processes` |
| `download` | `getfile` |
| `process` | `processes` |
| `netstat` | `connections` |
### Произвольные команды
Любой ввод, не соответствующий встроенной команде, рассматривается как произвольная команда и выполняется на удаленной машине через заглушку исполнителя B64. Примеры: `whoami`, `ipconfig`, `cat /etc/hostname`.
- Цели Windows: команда кодируется в Base64 UTF-16-LE и выполняется через `executor_b64.ps1` (блок скрипта PowerShell)
- Цели Linux/macOS: команда кодируется в Base64 UTF-8 и выполняется через `executor_b64.sh` (bash)
**Обнаружение конвейеров**: Команды, содержащие конвейеры (`|`), точки с запятой (`;`), перенаправления (`>>`) или подвыражения (`$(`), всегда оборачиваются в B64, даже если первое слово является встроенным глаголом LR. Например, `dir C:\ | Select-Object` проходит через B64, а не через встроенный `dir`.
### Управление библиотекой
| Команда | Описание |
|---------|-------------|
| `library` | Вывести все файлы в библиотеке MDE |
| `library refresh` | Принудительно обновить список библиотеки из API |
| `library upload <path>` | Загрузить локальный файл в библиотеку |
| `library delete <name>` | Удалить файл из библиотеки по имени |
| `library download <name>` | Скачать содержимое файла из библиотеки (Внутренний API: напрямую; Официальный API: через `getfile` из кэша библиотеки конечной точки после выбора машины — синхронизация может занять до 10 мин) |
### Управление действиями
| Команда | Описание |
|---------|-------------|
| `actions` | Вывести ожидающие/выполняющиеся действия для текущей машины |
| `actions all` | Вывести все последние действия на всех машинах |
| `actions cancel <id>` | Отменить действие по ID (поддерживается частичное совпадение) |
---
## Архитектура
### Внутренний и официальный API
Оболочка LaraC2 предоставляет два независимых пути API к одному и тому же бэкенду MDE Live Response. Внутренний API отражает модель сессии, похожую на WebSocket на портале, и обеспечивает ответы, близкие к реальному времени. Официальный API использует документированные конечные точки REST от Microsoft и подходит для автоматизации.
| | Внутренний API | Официальный API |
|---|---|---|
| Базовый URL | `security.microsoft.com/apiproxy/mtp/liveResponseApi/` | `api.securitycenter.microsoft.com/api/` |
| Сессия | Постоянная (keepalive 30 мин, авто-переподключение) | На команду (без состояния) |
| Интервал опроса | ~1 с (близко к реальному времени) | 2 с |
| Множественные команды | Последовательные в рамках общей сессии | Пакетные (до 5 на вызов API) |
| Аутентификация | Автономная (ESTS/ключ доступа/TOTP -> sccauth) | Учетные данные клиента OAuth2 или код устройства |
| Тайм-аут по умолчанию | 1800 с (сервер решает, не клиент) | 1800 с (сервер решает, не клиент) |
#### Что LaraC2 добавляет поверх сырого API
| Шаг | Сырой официальный API | Оболочка LaraC2 |
|------|-----------------|-------------|
| Загрузка заглушки | Вручную: создать multipart, POST, обработать конфликты | Автоматически при подключении, переопределение 409 |
| Кодирование B64 | Вручную: выбрать UTF-16LE/UTF-8 в зависимости от ОС | Автоопределение ОС, авто-кодирование |
| Построение RunScript | Вручную: JSON с параметрами ScriptName + Args | Ввести команду напрямую |
| Опрос + получение | Вручную: цикл + ссылка для скачивания + разбор JSON | Прозрачно: возвращает чистый вывод |
| Обработка ошибок | Вручную: проверять 400/401/403/409/429/503 | Автоматически: повтор, задержка, рекомендации |
| Множественные команды | Вручную: создать массив Commands[] | Автоматическая пакетная обработка до 5 |
### Ключевое ограничение
Официальный API и Внутренний API используют общую очередь действий для каждой машины. Они не могут выполняться одновременно на одной и той же машине.
### Ограничение скорости (прозрачное)
| Лимит | Значение | Обработка |
|-------|-------|----------|
| Команды LR в минуту | 10 | Ответ 429 с заголовком Retry-After |
| Загрузки библиотеки в минуту | 100 | Очередь со скользящим окном |
| Загрузки библиотеки в час | 1500 | Почасовой счетчик |
| HTTP 429 Too Many Requests | -- | Сон по заголовку Retry-After (по умолчанию 35 с) |
| ActiveRequestAlreadyExists | -- | Отменить конфликтующее действие + фиксированная задержка (10 с, затем 15 с до 12 повторных попыток) |
| Истечение Bearer токена (официальный) | ~1 час | Автообновление до истечения |
| Истечение sccauth (внутренний) | ~1 час | Незаметная повторная аутентификация, если сохранены учетные данные |
| Неактивность сессии LR | 30 минут | Авто-переподключение |
| Ротация XSRF | 4 минуты | Прозрачное обновление |
---
## Возможность работы в режиме, близком к реальному времени
Измеренные задержки в производственном арендаторе MDE на целях Windows, Linux и macOS:
| Операция | Внутренний API | Официальный API |
|-----------|-------------|-------------|
| `whoami` (B64) | 4-9 с | 20-46 с |
| `dir` (встроенная) | 2-4 с | 14-25 с |
| `processes` (встроенная) | 3-15 с | 20-175 с |
| `connections` (встроенная) | 2-4 с | ~15 с |
| `services` (встроенная) | 2-5 с | ~15 с |
| `hostname` (B64) | 4-7 с | 11-16 с |
| Подключение сессии (первая команда) | 9-15 с | Н/П (без состояния) |
| Переключение между машинами | 7-10 с | 15-30 с |
**Внутренний API: способен к работе в режиме, близком к реальному времени.** При повторном использовании сессии встроенные команды отвечают за 2-5 с. Это настолько близко к реальному времени, насколько позволяет MDE. Узким местом является агент SenseIR на целевой машине, а не фреймворк.
**Официальный API: уровень автоматизации.** Минимум ~15 с на команду из-за архитектуры без состояния (отправка, опрос, получение). Хорошо подходит для скриптовой автоматизации и CI/CD, а не для интерактивного использования.
---
## Поддержка разных ОС
Конечные точки Linux и macOS полностью поддерживаются через оба режима API.
| Целевая ОС | Среднее (Внутренний API) | Среднее (Официальный API) |
|-----------|-----------------|-----------------|
| Windows | ~7 с | ~30 с |
| Linux | ~6 с | ~26-33 с |
| macOS | ~6 с | ~26-33 с |
**На что обратить внимание**:
1. Заглушки `.sh` **должны** иметь окончания строк Unix (LF, а не CRLF), иначе bash выдаст ошибку "ambiguous redirect".
2. Загрузка библиотеки через официальный API **не** синхронизирует файлы `.sh` с конечными точками Linux/macOS. Сначала загрузите через внутренний API (портал) или через интерфейс портала Defender. После загрузки официальный API RunScript работает нормально.
3. `executor_b64.sh` работает на Linux и macOS после правильной загрузки.
---
## Тестирование
Набор тестов включает 712 автономных модульных тестов, 301 интеграционный тест официального API, 251 интеграционный тест внутреннего API, а также настраиваемый драйвер стресс-тестирования.
### Предварительные требования```powershell
Install-Module -Name Pester -MinimumVersion 5.0.0 -Force -Scope CurrentUser
Модульные тесты, покрывающие загрузку модулей, кодирование B64, построение команд, разрешение псевдонимов, токенизатор, ограничитель скорости, криптографию аутентификации, управление сессиями, пути ошибок и все потоки аутентификации с помощью Pester Mock.```powershell Invoke-Pester ./tests/shell/LaraC2Shell.Offline.Tests.ps1 -Output Detailed
### Внутренние API-тесты (требуются куки портала)
Интеграционные тесты, охватывающие sccauth auth, жизненный цикл сессии, все нативные команды, выполнение B64, кроссплатформенное нацеливание.```powershell
$env:LARAC2_SCCAUTH = 'your-sccauth-cookie'
$env:LARAC2_XSRF = 'your-xsrf-token'
Invoke-Pester ./tests/shell/LaraC2Shell.Internal.Tests.ps1 -Output Detailed
pwsh -File tests/shell/LaraC2Shell.Stress.Tests.ps1 -Config config.json -Mode official -Rounds 5
pwsh -File tests/shell/LaraC2Shell.Stress.Tests.ps1 -Config config.json -Mode both -Scenario crossos
### CI/CD (GitHub Actions)
| Job | Trigger | Platforms | Requirements |
|-----|---------|-----------|--------------|
| PSScriptAnalyzer Lint | Every push/PR | Ubuntu | None |
| Offline Tests | Every push/PR | Ubuntu + Windows + macOS | None |
| Online Tests (Official) | Conditional | Ubuntu | `LARAC2_ONLINE_TESTS` variable + `LARAC2_CONFIG` secret |
| Stress Tests | Manual dispatch | Ubuntu | `LARAC2_CONFIG` secret |
---
## Troubleshooting
| Error | Cause | Resolution |
|-------|-------|------------|
| `ActiveRequestAlreadyExists` | Another LR command is running on the target | Auto-handled (official mode): cancel conflicting action + fixed 10s/15s backoff up to 12 retries. Internal mode: wait-only. No user action needed. |
| HTTP 429 | Rate limit exceeded (10 cmds/min) | Auto-handled: sleeps for Retry-After period and retries. |
| "script not found" on Linux/macOS | .sh stub not synced to endpoint | Upload via Internal API or Defender portal UI. Official API uploads do not sync .sh files. |
| "ambiguous redirect" on Linux/macOS | .sh stub has CRLF line endings | Re-save with LF line endings and re-upload. |
| HTTP 400 on large command | B64 payload exceeds ~30 KB | Use `library upload` + `run <script>` instead. |
| HTTP 401 | Token/session expired | Shell auto-refreshes for client credentials, TOTP, and passkey. For other methods, type `connect`. |
| HTTP 403 | Insufficient permissions | Official: check `Machine.LiveResponse` + `Library.Manage` scopes. Internal: check Security Operator role. |
| HTTP 404 | Machine not found | Run `machines refresh` to reload. |
---
## Requirements
| Requirement | Detail |
|-------------|--------|
| PowerShell Core | 7.0 or later (`pwsh`) |
| MDE App Registration | Required for official mode (`Machine.LiveResponse` + `Library.Manage` permissions) |
| Operating System | Windows, Linux, or macOS (shell runs on any; targets can be any MDE-enrolled OS) |
All authentication is self-contained -- no external modules required. Internal mode auth flows are based on [XDRInternals](https://github.com/MSCloudInternals/XDRInternals) by Fabian Bader & Nathan McNulty.
---
## File Layout```
shell/
Invoke-MDEShell.ps1 Main shell entry point (REPL, dispatch, help)
modules/
Auth-Official.ps1 OAuth2 client credentials + device code
Auth-Internal.ps1 Self-contained ESTS/passkey/TOTP/TAP authentication
Auth-Crypto.ps1 Crypto helpers: TOTP, WebAuthn, passkey signing, Key Vault
Rate-Limiter.ps1 429/backoff/ActiveRequest handling
Invoke-LRCommand.ps1 Command execution (both modes, B64 stubs, multi-machine)
Get-Machines.ps1 Machine list + picker
Manage-Library.ps1 Library file management + auto-init stubs
Manage-Actions.ps1 Action list/cancel
config/
shell-config.example.json Config template (copy and fill in)
stubs/
executor_b64.ps1 Windows PS B64 executor (auto-uploaded)
executor_b64.sh Linux/macOS bash B64 executor (auto-uploaded)
tests/
shell/
LaraC2Shell.Offline.Tests.ps1 Unit tests (no tenant needed)
LaraC2Shell.Online.Tests.ps1 Integration tests (Official API)
LaraC2Shell.Internal.Tests.ps1 Integration tests (Internal API)
LaraC2Shell.Stress.Tests.ps1 Stress/throughput driver (configurable scenarios)
docs/
USER_GUIDE.md Step-by-step usage guide
COMMAND_REFERENCE.md All commands, routing, batching
ERROR_REFERENCE.md Error messages and fixes
PERFORMANCE_COMPARISON.md Stress test data and API comparison
См. LICENSE за условиями.
| Документ | Назначение |
|---|
| Руководство пользователя | Пошаговая настройка, аутентификация и работа |
| Справочник команд | Все команды, маршрутизация, пакетная обработка, автодополнение |
| Справочник ошибок | Коды HTTP, ошибки оболочки, ошибки аутентификации, исправления |
| Производительность | Задержка внутреннего и официального режимов, пропускная способность, лимиты |
| Архитектура | Внутреннее устройство, цепочки аутентификации, конечные точки, структура файлов |
| Участие | Как участвовать, тестировать, отправлять PR |
| Политика безопасности | Как сообщить об уязвимости конфиденциально |
| Ссылки | Предшествующие работы, связанные исследования, благодарности |
| Отказ от ответственности | Авторизация, благодарности |
| Ресурс | Автор | Описание |
|---|
| XDRInternals | Fabian Bader, Nathan McNulty | Потоки аутентификации внутреннего портала (ESTS, passkey, TOTP, TAP) |
| Running Arbitrary Commands | Jon Glass | Методы выполнения команд Live Response |
| Troubleshoot Live Response | Jeffrey Appel | Архитектура LR, WpnService, диагностика сессий |
| MDE Internals 0x05 | Olaf Hartong (FalconForce) | Телеметрия MDE для чувствительных действий, разработка детекций |
| DefenderHarvester | Olaf Hartong | Концепции экспорта телеметрии MDE |
| Run Live Response API | Microsoft | Официальная документация API |
| Library Methods API | Microsoft | Документация API управления библиотекой |