Add --json to submit, ls, and info for test/clone/remote flows. Document all JSON output formats in README. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
220 lines
5.6 KiB
Markdown
220 lines
5.6 KiB
Markdown
# rust-ectf-tools
|
|
|
|

|
|
|
|
Drop-in replacement for MITRE's `uvx ectf` CLI, rewritten in Rust with reliable serial I/O. Uses raw termios instead of pyserial to avoid macOS CDC-ACM data corruption bugs.
|
|
|
|
## Install
|
|
|
|
```bash
|
|
brew install taciturnaxolotl/tap/ectf-tools
|
|
```
|
|
|
|
Or build from source:
|
|
|
|
```bash
|
|
cargo build --release
|
|
```
|
|
|
|
## Usage
|
|
|
|
### HSM Host Tools
|
|
|
|
```bash
|
|
# List files on the HSM
|
|
ectf-tools tools /dev/tty.usbmodemXXX list 1a2b3c
|
|
|
|
# Write a file
|
|
ectf-tools tools /dev/tty.usbmodemXXX write 1a2b3c 0 0x4321 myfile.bin
|
|
|
|
# Read a file
|
|
ectf-tools tools /dev/tty.usbmodemXXX read 1a2b3c 1 ./output/
|
|
|
|
# Interrogate a connected HSM
|
|
ectf-tools tools /dev/tty.usbmodemXXX interrogate 1a2b3c
|
|
|
|
# Listen for another HSM
|
|
ectf-tools tools /dev/tty.usbmodemXXX listen
|
|
|
|
# Receive a file from another HSM
|
|
ectf-tools tools /dev/tty.usbmodemXXX receive 1a2b3c 0 1
|
|
|
|
# Run the hardware test suite
|
|
ectf-tools tools /dev/tty.usbmodemXXX test 1a2b3c 0x4321 /dev/tty.usbmodemYYY
|
|
|
|
# Run tests without a second HSM
|
|
ectf-tools tools /dev/tty.usbmodemXXX test 1a2b3c 0x4321 --no-transfer
|
|
|
|
# Output test results as JSON (for CI)
|
|
ectf-tools tools /dev/tty.usbmodemXXX test 1a2b3c 0x4321 --no-transfer --json
|
|
```
|
|
|
|
### API Commands
|
|
|
|
```bash
|
|
# Configure your API credentials
|
|
ectf-tools config --token <TOKEN> --git-url <GIT_URL>
|
|
|
|
# Submit a design for testing
|
|
ectf-tools api test submit <COMMIT_HASH>
|
|
|
|
# List recent test flows
|
|
ectf-tools api test ls
|
|
|
|
# Get details on a specific flow
|
|
ectf-tools api test info <FLOW_ID>
|
|
|
|
# Download job output
|
|
ectf-tools api test get <JOB_ID> output.tar.gz
|
|
|
|
# Submit to handoff
|
|
ectf-tools api submit <COMMIT_HASH>
|
|
|
|
# List and download attack packages
|
|
ectf-tools api list
|
|
ectf-tools api get <PACKAGE_NAME>
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
For CI environments, you can configure the tool entirely via environment variables instead of the config file:
|
|
|
|
| Variable | Description | Required |
|
|
|---|---|---|
|
|
| `ECTF_TOKEN` | API bearer token | Yes (with `ECTF_GIT_URL`) |
|
|
| `ECTF_GIT_URL` | Git repository URL | Yes (with `ECTF_TOKEN`) |
|
|
| `ECTF_API_URL` | API base URL (default: `https://api.ectf.mitre.org`) | No |
|
|
|
|
If both `ECTF_TOKEN` and `ECTF_GIT_URL` are set, no config file is needed. If a config file exists, env vars override individual fields.
|
|
|
|
### JSON Output (`--json`)
|
|
|
|
Most commands support `--json` for machine-readable output. The process exit code is still non-zero on failure.
|
|
|
|
#### `tools test --json`
|
|
|
|
```json
|
|
{
|
|
"total": 15,
|
|
"passed": 14,
|
|
"failed": 1,
|
|
"tests": [
|
|
{
|
|
"name": "list_empty",
|
|
"passed": true,
|
|
"duration_secs": 0.123
|
|
},
|
|
{
|
|
"name": "bad_pin",
|
|
"passed": false,
|
|
"duration_secs": 1.234,
|
|
"error": "Expected bad pin to fail, but it succeeded"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### `api test submit --json` / `api clone submit --json` / `api submit --json`
|
|
|
|
```json
|
|
{
|
|
"flow": "test",
|
|
"id": "abc12345-1234-1234-1234-123456789abc"
|
|
}
|
|
```
|
|
|
|
#### `api test ls --json` / `api clone ls --json` / `api remote ls --json`
|
|
|
|
```json
|
|
{
|
|
"flows": [
|
|
{
|
|
"id": "abc12345-1234-1234-1234-123456789abc",
|
|
"submitted": "2026-02-11T22:05:47.000000Z",
|
|
"status": "succeeded",
|
|
"completed": true
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### `api test info --json` / `api clone info --json` / `api remote info --json`
|
|
|
|
```json
|
|
{
|
|
"flow": "test",
|
|
"id": "abc12345-1234-1234-1234-123456789abc",
|
|
"submitted": "2026-02-11T22:05:47.000000Z",
|
|
"status": "succeeded",
|
|
"completed": true,
|
|
"params": {
|
|
"git_url": "https://github.com/example/repo.git",
|
|
"commit_hash": "abc1234"
|
|
},
|
|
"jobs": [
|
|
{
|
|
"name": "build",
|
|
"id": "def12345-1234-1234-1234-123456789abc",
|
|
"status": "succeeded",
|
|
"has_artifacts": true,
|
|
"private": false
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Hardware Bootloader Tools (MSPM0L2228)
|
|
|
|
```bash
|
|
# Check bootloader version and status
|
|
ectf-tools hw /dev/tty.usbmodemXXX status
|
|
|
|
# Erase the current design
|
|
ectf-tools hw /dev/tty.usbmodemXXX erase
|
|
|
|
# Flash an image (name auto-derived from filename for unprotected images)
|
|
ectf-tools hw /dev/tty.usbmodemXXX flash design.bin
|
|
ectf-tools hw /dev/tty.usbmodemXXX flash design.bin --name mydesign
|
|
|
|
# Start the flashed design
|
|
ectf-tools hw /dev/tty.usbmodemXXX start
|
|
|
|
# Erase + flash + start in one step (file or directory with hsm.bin)
|
|
ectf-tools hw /dev/tty.usbmodemXXX reflash ./build/
|
|
ectf-tools hw /dev/tty.usbmodemXXX reflash engineer.hsm/hsm.bin
|
|
|
|
# Get a file digest from the secure bootloader
|
|
ectf-tools hw /dev/tty.usbmodemXXX digest 0
|
|
```
|
|
|
|
### Hardware Bootloader Tools (MAX78000FTHR)
|
|
|
|
```bash
|
|
# Flash a design
|
|
ectf-tools hw /dev/tty.usbmodemXXX flash-fthr /dev/tty.usbmodemYYY image.bin
|
|
|
|
# Permanently unlock the secure bootloader (irreversible!)
|
|
ectf-tools hw /dev/tty.usbmodemXXX unlock-fthr /dev/tty.usbmodemYYY secrets.json --force --force
|
|
```
|
|
|
|
### Verbosity
|
|
|
|
- `-v` — protocol-level debug (headers, ACKs, chunk sizes)
|
|
- `-vv` — raw byte-level trace with xxd-style hexdump
|
|
|
|
## Why not pyserial?
|
|
|
|
pyserial has known data corruption issues on macOS with CDC-ACM devices (like the MAX78000). This tool opens the serial port directly with proper termios configuration, flushes the input buffer on open, and uses `O_NONBLOCK` to avoid blocking on carrier detect.
|
|
|
|
<p align="center">
|
|
<img src="https://raw.githubusercontent.com/taciturnaxolotl/carriage/main/.github/images/line-break.svg" />
|
|
</p>
|
|
|
|
<p align="center">
|
|
<i><code>© 2026-present <a href="https://dunkirk.sh">Kieran Klukas</a></code></i>
|
|
</p>
|
|
|
|
<p align="center">
|
|
<a href="https://github.com/taciturnaxolotl/rust-ectf-tools/blob/main/LICENSE.md"><img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=MIT&logoColor=d9e0ee&colorA=363a4f&colorB=b7bdf8"/></a>
|
|
</p>
|