Skip to content

Commit ea956ec

Browse files
akefallonitisclaude
andcommitted
Production readiness: complete docs rewrite, cross-OS fix, UX consolidation
Framework fixes: - CRLF→LF fix for .sh stubs (was breaking bash on Linux/macOS with "ambiguous redirect") - .gitattributes: enforce LF for .sh files - Pipeline detection: commands with pipes/semicolons now B64-wrap even if first word is native LR verb - Rate-Limiter: ActiveRequest retry message shows correct limit (12, not 5) - Auth-Internal: session expiry message simplified to "Type 'connect' to re-authenticate" - Invoke-LRCommand: default timeout 1800s (server decides, not client) - Manage-Library: warns when .sh uploaded via Official API (doesn't sync to Linux/macOS) - Removed lara_loader.sh (executor_b64.sh works on all platforms once properly uploaded) UX consolidation: - Unified auth menu (7 methods in one screen, mode derived from choice) - connect command re-authenticates when session expired - mode command informational only (no manual switching) - session/session list for awareness - Dynamic error handling with server response parsing - Typo detection for shell commands - 403 DisallowedOperation: specific device group guidance Cross-OS findings: - Linux/macOS PROVEN WORKING via both APIs (Internal: 6.2s avg, Official: 26-33s avg) - .sh stubs MUST have Unix line endings (LF) - Official API library upload doesn't sync .sh to Linux/macOS — upload via Internal API/portal first - Once stubs are properly uploaded, Official API RunScript works fine on all 3 platforms Documentation: complete rewrite of all 7 doc files from scratch: - README.md, ARCHITECTURE.md, USER_GUIDE.md, COMMAND_REFERENCE.md - ERROR_REFERENCE.md, PERFORMANCE_COMPARISON.md, tests/README.md Test results (2026-04-03): - Offline: 736/736 PASS (100%) - Internal Pester: 251/251 PASS (100%) - Stress Internal (blackhat): 23/26 PASS (88%) - Stress Official (larabond): 25/26 PASS (96%) - Stress CrossOS Internal (Win+Lin+Mac): 36/36 PASS (100%) - Stress CrossOS Official (Win+Lin+Mac): 30/36 PASS (83%) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e1dfb0f commit ea956ec

17 files changed

Lines changed: 1235 additions & 1052 deletions

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
*.yml text eol=lf
22
*.yaml text eol=lf
3+
*.sh text eol=lf

ARCHITECTURE.md

Lines changed: 189 additions & 114 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 100 additions & 122 deletions
Large diffs are not rendered by default.

docs/COMMAND_REFERENCE.md

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# LaraC2 Shell -- Command Reference
22

3-
Complete reference for all commands, native LR operations, aliases, and command
4-
routing logic in the MDE Live Response Interactive Shell.
3+
Complete reference for all commands, native LR operations, aliases, and command routing logic.
54

65
---
76

@@ -15,14 +14,12 @@ These commands are handled by the REPL dispatcher and do not execute on the remo
1514
| `help commands` | List all 25 native LR commands with descriptions. | `help commands` |
1615
| `help aliases` | Show all command aliases. | `help aliases` |
1716
| `mode` | Display the current API mode (official or internal). | `mode` |
18-
| `mode official` | Switch to Official API mode and re-authenticate. | `mode official` |
19-
| `mode internal` | Switch to Internal API mode and re-authenticate. | `mode internal` |
2017
| `status` | Show connection status: API mode, auth method/state, token expiry, session info, selected machine, OS, working directory. | `status` |
21-
| `config` | Show Live Response configuration (unsigned scripts allowed, LR enabled). Works in both modes. | `config` |
22-
| `disconnect` | Disconnect the current LR session (internal mode) and clear machine selection. | `disconnect` |
18+
| `config` | Show Live Response configuration (unsigned scripts allowed, LR enabled). | `config` |
19+
| `disconnect` | Disconnect the current LR session and clear machine selection. | `disconnect` |
2320
| `machines` | List enrolled machines (cached 5 min) and prompt for selection. | `machines` |
2421
| `machines refresh` | Force-reload the machine list from the API, then prompt for selection. | `machines refresh` |
25-
| `connect [name\|id]` | Switch the active target machine. By name substring, ID prefix, or interactive picker if omitted. Auto-disconnects old session in internal mode. | `connect`, `connect blackhat`, `connect abc123` |
22+
| `connect [name\|id]` | Re-authenticate if expired, then select a machine. By name substring, ID prefix, or interactive picker if omitted. Auto-disconnects old session in internal mode. | `connect`, `connect blackhat`, `connect abc123` |
2623
| `library` | List all files in the MDE Library. | `library` |
2724
| `library refresh` | Force-refresh the library file list from API. | `library refresh` |
2825
| `library upload <path>` | Upload a local file to the MDE Library. | `library upload ./myscript.ps1` |
@@ -31,49 +28,46 @@ These commands are handled by the REPL dispatcher and do not execute on the remo
3128
| `actions` | List InProgress/Pending actions for the current machine. | `actions` |
3229
| `actions all` | List all recent actions across all statuses. | `actions all` |
3330
| `actions cancel <id>` | Cancel an action by full or partial GUID (prefix match). | `actions cancel abc123` |
34-
| `multi <command>` | Run a command on multiple machines simultaneously. Supports `-top N` and `-filter <pattern>` options. | `multi whoami`, `multi -top 3 hostname` |
31+
| `multi <command>` | Run a command on multiple machines. Supports `-top N` and `-filter <pattern>`. | `multi whoami`, `multi -top 3 hostname` |
32+
| `session` | Show current session info (machine, age, CWD). | `session` |
33+
| `session list` | Show all cached sessions with age and idle time. | `session list` |
3534
| `exit` / `quit` / `q` | Exit the shell. Disconnects the internal session first. | `exit` |
3635

3736
---
3837

3938
## Native LR Commands (25)
4039

41-
These commands are recognized by the shell as native Live Response operations. In official
42-
mode, `getfile`, `putfile`, and `run` are sent as their native API types (`GetFile`,
43-
`PutFile`, `RunScript`). All other native commands are executed via the B64 executor stub
44-
in official mode. In internal mode, all native commands are sent using the session's cached
45-
command definitions with proper `param_id`/`value` pairs.
40+
These commands are recognized as native Live Response operations. In internal mode, all native commands are sent using the session's cached command definitions with proper `param_id`/`value` pairs. In official mode, `getfile`, `putfile`, and `run` use their native API types (`GetFile`, `PutFile`, `RunScript`); all other native commands go through the B64 executor.
4641

47-
| Command | Description | OS | API Mode | Example |
48-
|---------|-------------|-----|----------|---------|
42+
| Command | Description | OS | Mode | Example |
43+
|---------|-------------|-----|------|---------|
4944
| `processes` | List running processes (PID, name, memory, CPU). | All | Both | `processes` |
50-
| `connections` | List active network connections (local/remote address, port, protocol). | All | Both | `connections` |
45+
| `connections` | List active network connections. | All | Both | `connections` |
5146
| `getfile <path>` | Download a file from the remote machine. | All | Both | `getfile C:\Windows\System32\drivers\etc\hosts` |
52-
| `putfile <name> [dest]` | Upload a file from the library to the remote working directory. Optional destination path. | All | Both | `putfile myscript.ps1` |
47+
| `putfile <name>` | Upload a file from the library to the remote working directory. | All | Both | `putfile myscript.ps1` |
5348
| `run <script> [args]` | Run a script from the MDE Library on the machine. | All | Both | `run myscript.ps1 -Param1 value1` |
5449
| `cd <path>` | Change the working directory on the target. Internal mode updates the session directory. | All | Both | `cd C:\Windows\Temp` |
5550
| `dir [path]` | List directory contents. | All | Both | `dir`, `dir C:\Windows\Temp` |
56-
| `findfile <name>` | Search for a file by name across all drives/volumes. Timeout: 1800s (30 min). | All | Both | `findfile suspicious.exe` |
57-
| `trace` | Capture a diagnostic ETW trace. Timeout: 600s (10 min). | All | Both | `trace -etl` |
58-
| `analyze <path>` | Submit a file for deep analysis by MDE. Timeout: 600s (10 min). | All | Both | `analyze C:\Users\Public\suspicious.exe` |
51+
| `findfile <name>` | Search for a file by name across all drives/volumes. Timeout: 1800s. | All | Both | `findfile suspicious.exe` |
52+
| `trace` | Capture a diagnostic ETW trace. Timeout: 600s. | All | Both | `trace -etl` |
53+
| `analyze <path>` | Submit a file for deep analysis by MDE. Timeout: 600s. | All | Both | `analyze C:\Users\Public\suspicious.exe` |
5954
| `remediate <path>` | Quarantine/remediate a file on the remote machine. | All | Both | `remediate file C:\malware\suspicious.exe` |
6055
| `undo <actionId>` | Undo a previous remediation action. | All | Both | `undo file C:\restored\file.exe` |
6156
| `registry <key>` | Query registry keys and values (read-only). | Windows | Both | `registry HKLM\Software\Microsoft` |
62-
| `scheduledtasks` | List scheduled tasks (Windows: task names/status; Linux: cron/systemd). | Windows | Both | `scheduledtasks` |
63-
| `persistence` | Check common persistence mechanisms (autoruns, services, startup, cron). | All | Both | `persistence` |
57+
| `scheduledtasks` | List scheduled tasks. | Windows | Both | `scheduledtasks` |
58+
| `persistence` | Check common persistence mechanisms. | All | Both | `persistence` |
6459
| `drivers` | List loaded drivers. | Windows | Both | `drivers` |
65-
| `services` | List services (Windows: name, display name, status; Linux: running daemons). | All | Both | `services` |
60+
| `services` | List services. | All | Both | `services` |
6661
| `startupfolders` | List startup folder contents. | Windows | Both | `startupfolders` |
67-
| `fileinfo <path>` | Get detailed file information (size, timestamps, attributes, hash, signature). 30 GB limit. | All | Both | `fileinfo C:\Windows\System32\cmd.exe` |
62+
| `fileinfo <path>` | Get detailed file information (size, timestamps, hash, signature). 30 GB limit. | All | Both | `fileinfo C:\Windows\System32\cmd.exe` |
6863
| `prefetch` | List prefetch data (recently executed programs). | Windows | Both | `prefetch` |
69-
| `log` | View diagnostic logs on the target machine. | All | Both | `log` |
64+
| `log` | View diagnostic logs. | All | Both | `log` |
7065
| `jobs` | List background jobs in the current LR session. | All | Internal | `jobs` |
7166
| `fg <jobId>` | Bring a background job to the foreground. | All | Internal | `fg 1` |
7267

7368
### Windows-Only Commands
7469

75-
The following commands are designed for Windows targets and will produce a warning
76-
if sent to a Linux or macOS target:
70+
The following commands produce a warning if sent to a Linux or macOS target:
7771

7872
- `registry`
7973
- `scheduledtasks`
@@ -83,16 +77,14 @@ if sent to a Linux or macOS target:
8377

8478
### Per-Command Timeouts
8579

86-
Some commands have extended timeouts to account for their expected execution time:
87-
8880
| Command | Timeout | Reason |
8981
|---------|---------|--------|
90-
| `analyze` | 600s (10 min) | Deep analysis can be slow. |
91-
| `findfile` | 1800s (30 min) | Full-disk search. MS API limit. |
92-
| `trace` | 600s (10 min) | ETW trace collection. |
93-
| `getfile` | 1800s (30 min) | Large file downloads. MS API limit. |
82+
| `analyze` | 600s (10 min) | Deep analysis can be slow |
83+
| `findfile` | 1800s (30 min) | Full-disk search (MS API limit) |
84+
| `trace` | 600s (10 min) | ETW trace collection |
85+
| `getfile` | 1800s (30 min) | Large file downloads (MS API limit) |
9486

95-
All other commands default to 300s (5 min), configurable via `commandTimeoutSeconds` in config.
87+
All other commands use the default timeout: 1800s (server decides). The client-side `commandTimeoutSeconds` config value provides an additional ceiling.
9688

9789
---
9890

@@ -106,25 +98,25 @@ All other commands default to 300s (5 min), configurable via `commandTimeoutSeco
10698
| `process` | `processes` | List running processes |
10799
| `netstat` | `connections` | List network connections |
108100

109-
Aliases are resolved before command execution. Both the alias and the full command
110-
name work identically.
101+
Aliases are resolved before command execution. Both the alias and the full command name work identically.
111102

112103
---
113104

114105
## Arbitrary Commands
115106

116-
Any input that is not a shell command, native LR command, or alias is treated as an
117-
arbitrary command and executed on the remote machine via the B64 executor stub.
107+
Any input that is not a shell command, native LR command, or alias is treated as an arbitrary command and executed on the remote machine via the B64 executor stub.
118108

119109
**How it works:**
120110

121111
1. The command string is Base64-encoded:
122112
- **Windows targets**: UTF-16-LE encoding, then Base64
123113
- **Linux/macOS targets**: UTF-8 encoding, then Base64
124-
2. The encoded payload is passed as the `-B64` argument to the executor stub
114+
2. The encoded payload is sent as the argument to the executor stub
125115
3. The executor decodes and executes the command:
126-
- **Windows**: `executor_b64.ps1` decodes and runs via PowerShell `Invoke-Expression`
127-
- **Linux/macOS**: `executor_b64.sh` decodes and runs via `bash`
116+
- **Windows**: `executor_b64.ps1` decodes and runs via PowerShell `[ScriptBlock]::Create()`
117+
- **Linux/macOS**: `executor_b64.sh` decodes and pipes through `bash`
118+
119+
**Pipeline detection**: Commands containing pipes (`|`), semicolons (`;`), redirects (`>>`), or subexpressions (`$(`) are always B64-wrapped, even if the first word is a native LR verb. For example, `dir C:\ | Select-Object` goes through B64, not native `dir`.
128120

129121
**Examples:**
130122

@@ -136,9 +128,7 @@ cat /etc/passwd
136128
uname -a
137129
```
138130

139-
**Size limits:** Commands are reliable up to ~30KB after encoding. Payloads over 35KB
140-
may timeout, and 40KB+ are typically rejected by the API. For large scripts, use
141-
`library upload` + `run <script>` instead.
131+
**Size limits:** Commands are reliable up to ~30KB after encoding. Payloads over 35KB may timeout, and 40KB+ are typically rejected. For large scripts, use `library upload` + `run <script>` instead.
142132

143133
---
144134

@@ -151,7 +141,7 @@ User Input
151141
|
152142
v
153143
1. Shell command? (help, machines, library, actions, multi, mode, status, config,
154-
connect, disconnect, exit/quit/q)
144+
connect, disconnect, session, exit/quit/q)
155145
--> YES: Handled by the REPL dispatcher. No remote execution.
156146
--> NO: Continue...
157147
|
@@ -163,11 +153,13 @@ User Input
163153
v
164154
3. Native LR command or alias?
165155
--> YES (alias): Resolve alias to canonical name, then...
166-
--> YES (native): Route based on API mode:
167-
- Official: getfile/putfile/run use native API types (GetFile/PutFile/RunScript).
168-
All other native commands go through B64 executor.
169-
- Internal: All native commands sent using session command definitions
170-
with proper param_id/value pairs.
156+
--> Has pipes/semicolons/redirects/subexpressions?
157+
--> YES: Skip native routing, go to step 5 (B64 wrap)
158+
--> NO: Route as native command:
159+
- Official: getfile/putfile/run use native API types.
160+
All others go through B64 executor.
161+
- Internal: All native commands sent using session command
162+
definitions with proper param_id/value pairs.
171163
--> NO: Continue...
172164
|
173165
v
@@ -187,8 +179,7 @@ User Input
187179

188180
## Multi-Command Batching (Official Mode)
189181

190-
Official mode supports sending up to 5 `RunScript` commands in a single API call.
191-
This is handled internally by `Invoke-LRCommandOfficial`:
182+
Official mode supports sending up to 5 `RunScript` commands in a single API call. This is handled internally by `Invoke-LRCommandOfficial`:
192183

193184
- Commands are batched in groups of 5
194185
- Each batch is sent as one `POST /machines/{id}/runliveresponse` with a `Commands` array
@@ -208,9 +199,7 @@ Run a single command across multiple machines simultaneously.
208199
| `multi -top N <command>` | Run on first N active | `multi -top 3 hostname` |
209200
| `multi -filter <pattern> <command>` | Run on matching machines | `multi -filter ws* processes` |
210201

211-
The `multi` command filters enrolled machines by `healthStatus -eq 'Active'`, then pipes
212-
them to `Invoke-LRCommandMultiMachine`. Results are displayed as a table with MachineName,
213-
Status, TimeMs, and a truncated Output preview.
202+
The `multi` command filters enrolled machines by `healthStatus -eq 'Active'`, then runs the command on each. Results are displayed as a table with MachineName, Status, TimeMs, and a truncated Output preview.
214203

215204
**Internal API**: Uses persistent sessions per machine (2-5s per machine).
216205
**Official API**: Creates separate runliveresponse actions (15-30s per machine).
@@ -236,7 +225,6 @@ The shell registers PSReadLine tab completion for:
236225
- `library`: `upload`, `delete`, `download`, `refresh`
237226
- `actions`: `all`, `cancel`, `list`
238227
- `machines`: `refresh`
239-
- `mode`: `official`, `internal`
240228
- `multi`: `-top`, `-filter`
241229
- `help`: All commands plus `commands` and `aliases`
242230
- **`connect` subcommand**: Machine names from the cached machine list

0 commit comments

Comments
 (0)