用于 Microsoft Defender for Endpoint 实时响应的跨平台交互式 Shell。
| 功能 | 详情 |
|---|---|
| 平台 | PowerShell Core 7.0+(Windows、Linux、macOS) |
| API 模式 | 内部(门户,近实时)和官方(公共,无状态) |
| 执行 | 任意命令 + 25 个原生 LR 命令 |
| 认证 | 7 种认证方法,统一菜单,自动刷新 |
| 许可证 | MIT |
LaraC2 Shell 通过两个独立的 API 路径连接到 MDE 实时响应——内部门户 API(持久会话,延迟约 2-5 秒)和官方公共 API(每命令,延迟约 20-60 秒)。它自动上传执行器存根,透明处理速率限制,并提供完整的 REPL,支持机器管理、库管理和内置帮助系统。
connect 命令重新认证multi 命令,支持名称模式过滤和限制前 N 个结果Machine.LiveResponse + Library.Manage 权限的 MDE 应用注册(官方模式)git clone https://github.com/akefallonitis/larac2shell.git cd larac2shell pwsh -File shell/Invoke-MDEShell.ps1
就这样。Shell在首次启动时提供一个统一的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` | Azure AD 租户 ID |
| `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 密钥、cookie)均以交互方式提示,且从不持久化到磁盘。
---
## 认证方法
Shell 在启动时提供一个统一的 7 方法认证菜单。模式(内部/官方)由选择决定。
| # | 模式 | 方法 | 方式 | 自动刷新 |
|---|------|--------|-----|--------------|
| 1 | 内部 | 凭据 + TOTP | 交互式提示 | 是(静默)——仅当提供了 TOTP 密钥时。使用推送/SMS MFA 时,会话无法自动刷新。 |
| 2 | 内部 | 软件通行密钥 | `-PasskeyPath` 参数或提示 | 是(静默) |
| 3 | 内部 | ESTS cookie | 交互式提示 | 否(约 24 小时) |
| 4 | 内部 | 临时访问通行证 | 交互式提示 | 否(一次性) |
| 5 | 内部 | 直接 sccauth + XSRF | 交互式提示 | 否(约 1 小时)——XSRF 自动刷新不适用;Shell 不会自动刷新直接提供的 cookie。 |
| 6 | 官方 | 设备代码 | 浏览器登录 | 否(约 1 小时) |
| 7 | 官方 | 客户端凭据 | 配置文件 | 是(静默) |
`connect` 命令在会话过期时重新认证,使用最初选择的相同方法。没有自动刷新的方法会再次以交互方式提示。
**内存中凭据处理**:对于方法 1,提供的密码和 TOTP 密钥在 Shell 进程生命周期内保留在内存中(作为纯字符串,位于 `$script:Int_ReauthParams` 中),以便无人值守地静默重新认证。这些字符串对象位于 PowerShell 运行空间中;它们不会被序列化到磁盘或通过命令行传递。如果这种暴露对你的威胁模型不可接受,请使用方法 2(通行密钥/HSM)或方法 7(客户端凭据)。
---
## Shell 命令
### Shell 控制
| 命令 | 描述 |
|---------|-------------|
| `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` | 退出 Shell |
### 机器管理
| 命令 | 描述 |
|---------|-------------|
| `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` | 列出预取数据(仅限 Windows) |
| `log` | 查看诊断日志 |
| `jobs` | 列出后台作业(内部模式) |
| `fg <jobId>` | 将后台作业置于前台(内部模式) |
| `library` | 管理库文件(列出、上传、下载、删除) |
| `status` | 显示会话状态和诊断信息 |
### 命令别名
| 别名 | 解析为 |
|-------|-------------|
| `ls` | `dir` |
| `ps` | `processes` |
| `download` | `getfile` |
| `process` | `processes` |
| `netstat` | `connections` |
### 任意命令
任何与内置命令不匹配的输入都将被视为任意命令,并通过 B64 执行器存根在远程机器上执行。示例:`whoami`、`ipconfig`、`cat /etc/hostname`。
- Windows 目标:命令将编码为 UTF-16-LE Base64,通过 `executor_b64.ps1`(PowerShell ScriptBlock)执行
- Linux/macOS 目标:命令将编码为 UTF-8 Base64,通过 `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 与官方 API
LaraC2 Shell 暴露两条独立的 API 路径到同一 MDE Live Response 后端。内部 API 镜像门户的类 WebSocket 会话模型,提供近实时响应。官方 API 使用微软官方文档的 REST 端点,适用于自动化。
| | 内部 API | 官方 API |
|---|---|---|
| 基础 URL | `security.microsoft.com/apiproxy/mtp/liveResponseApi/` | `api.securitycenter.microsoft.com/api/` |
| 会话 | 持久(30 分钟保活,自动重连) | 按命令(无状态) |
| 轮询间隔 | 约 1 秒(近实时) | 2 秒 |
| 多命令 | 共享会话内顺序执行 | 批量处理(每次 API 调用最多 5 个) |
| 认证 | 自包含(ESTS/通行密钥/TOTP -> sccauth) | OAuth2 客户端凭据或设备代码 |
| 默认超时 | 1800 秒(由服务器决定,非客户端) | 1800 秒(由服务器决定,非客户端) |
#### LaraC2 在原始 API 之上增加了什么
| 步骤 | 原始官方 API | LaraC2 Shell |
|------|-----------------|-------------|
| 存根上传 | 手动:构建 multipart、POST、处理冲突 | 连接时自动处理,409 覆盖 |
| B64 编码 | 手动:根据操作系统选择 UTF-16LE/UTF-8 | 自动检测操作系统,自动编码 |
| 构建 RunScript | 手动:包含 ScriptName + Args 参数的 JSON | 直接输入命令 |
| 轮询并获取 | 手动:循环 + 下载链接 + 解析 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 次重试) |
| 持有者令牌过期(官方) | 约 1 小时 | 过期前自动刷新 |
| sccauth 过期(内部) | 约 1 小时 | 若凭据已存储,则静默重新认证 |
| LR 会话不活动 | 30 分钟 | 自动重连 |
| XSRF 轮换 | 4 分钟 | 透明刷新 |
---
## 近实时 Shell 可行性
在 Windows、Linux 和 macOS 目标上的生产 MDE 租户中测量的延迟:
| 操作 | 内部 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 门户 UI 上传。上传后,官方 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 测试(需要 portal cookies)
集成测试覆盖 sccauth 认证、会话生命周期、所有原生命令、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)
| 任务 | 触发器 | 平台 | 要求 |
|-----|---------|-----------|--------------|
| PSScriptAnalyzer Lint | 每次推送/PR | Ubuntu | 无 |
| 离线测试 | 每次推送/PR | Ubuntu + Windows + macOS | 无 |
| 在线测试(官方) | 条件触发 | Ubuntu | `LARAC2_ONLINE_TESTS` 变量 + `LARAC2_CONFIG` 密钥 |
| 压力测试 | 手动触发 | Ubuntu | `LARAC2_CONFIG` 密钥 |
---
## 故障排除
| 错误 | 原因 | 解决方法 |
|-------|-------|------------|
| `ActiveRequestAlreadyExists` | 目标上正在运行另一条 LR 命令 | 自动处理(官方模式):取消冲突操作 + 固定 10s/15s 退避,最多重试 12 次。内部模式:仅等待。无需用户操作。 |
| HTTP 429 | 速率限制超出(10 条指令/分钟) | 自动处理:在 Retry-After 期间休眠并重试。 |
| Linux/macOS 上的“script not found” | .sh 存根未同步到端点 | 通过内部 API 或 Defender 门户 UI 上传。官方 API 上传不会同步 .sh 文件。 |
| Linux/macOS 上的“ambiguous redirect” | .sh 存根具有 CRLF 行尾 | 使用 LF 行尾重新保存并重新上传。 |
| 大型命令上的 HTTP 400 | B64 负载超过约 30 KB | 改用 `library upload` + `run <script>`。 |
| HTTP 401 | 令牌/会话已过期 | Shell 会自动刷新客户端凭据、TOTP 和通行密钥。对于其他方法,请输入 `connect`。 |
| HTTP 403 | 权限不足 | 官方模式:检查 `Machine.LiveResponse` + `Library.Manage` 作用域。内部模式:检查安全操作员角色。 |
| HTTP 404 | 未找到计算机 | 运行 `machines refresh` 重新加载。 |
---
## 要求
| 要求 | 详情 |
|-------------|--------|
| PowerShell Core | 7.0 或更高版本(`pwsh`) |
| MDE 应用注册 | 官方模式必需(`Machine.LiveResponse` + `Library.Manage` 权限) |
| 操作系统 | Windows、Linux 或 macOS(Shell 可在任意系统上运行;目标可以是任何 MDE 注册的 OS) |
所有认证均为自包含——无需外部模块。内部模式认证流程基于 [XDRInternals](https://github.com/MSCloudInternals/XDRInternals)(作者:Fabian Bader & Nathan McNulty)。
---
## 文件布局```
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。
| 文档 | 用途 |
|---|
| 用户指南 | 分步设置、认证和操作 |
| 命令参考 | 所有命令、路由、批处理、Tab 补全 |
| 错误参考 | HTTP 状态码、Shell 错误、认证错误、修复方法 |
| 性能对比 | 内部与官方 API 的延迟、吞吐量、限制 |
| 架构 | 内部结构、认证链、端点、文件布局 |
| 贡献指南 | 如何贡献、测试、提交 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 文档 |