workflows

package
v0.597.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Overview

Package workflows implements composite pentest flows that orchestrate several Flipper primitives + LLM reasoning behind a single LLM-callable tool. Each workflow is a self-contained Go function that:

  • calls primitives via the shared Deps surface (never re-implementing low-level CLI);
  • records each sub-step to the audit log at level=action;
  • honours ctx cancellation (partial JSON result, next_steps indicating the cancellation);
  • returns a single JSON string with {summary, phases[], next_steps[]} plus workflow-specific fields so the calling LLM can both summarise narratively and drive follow-up actions.

The package deliberately avoids introducing new Flipper CLI primitives — if a workflow needs something it cannot compose from existing methods on flipper.Flipper / marauder.Marauder, that's a bug in Phase 1 and should be surfaced, not papered over here.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BadUSBTargetProfile

func BadUSBTargetProfile(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

BadUSBTargetProfile generates a DuckyScript payload tailored to a described target, deploys it to the Flipper SD card, and optionally launches it via the BadUSB FAP. The workflow binds together the three primitives (generate → deploy → run) so the LLM can kick off a vetted payload with a single call.

Risk is High: the generated script lands on the Flipper SD card and, if auto_run=true, executes as keyboard input on whatever host the Flipper is connected to.

Params:

  • description (string, required): the payload's intended behaviour. Passed verbatim to the Generator LLM.
  • target_os (string, required): "windows" | "linux" | "macos".
  • auto_run (bool, default false): launch BadUSB FAP after deploy.
  • path (string, default /ext/badusb/generated_payload.txt): SD path.

func GarageDoorTriage

func GarageDoorTriage(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

GarageDoorTriage scans each frequency, saves any RX captures to /ext/subghz, decodes them, and aggregates the results with an attack suggestion. Receive-only — does NOT call subghz_transmit.

Risk is Medium (RX only, but writes files).

Params:

  • frequencies ([]int, optional): override the frequency list.
  • per_freq_seconds (int, default 5): per-frequency capture length.

func HWReconBlackbox

func HWReconBlackbox(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

HWReconBlackbox probes an unknown PCB attached to the Flipper GPIO header and returns an aggregated recon report. Probes: i2c scan, onewire search, per-pin gpio reads, bt hci_info (metadata), and device_info.

Risk is Low — all steps are read-only scans.

Params:

  • gpios ([]string, optional): override the pin list to sample.

func Mousejack added in v0.3.1

func Mousejack(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

Mousejack composes the three artefacts the NRF24 Mouse Jacker engagement needs, in the order an operator would actually run them:

  1. Read existing sniffer output (addresses.txt). If it's empty, tell the operator to run nrf24_sniff_start and come back — there's no CLI path to the sniffer, so the workflow can't scan autonomously.
  2. Build a DuckyScript payload targeting the identified host OS and write it to /ext/mousejacker/<name>.txt. The BadUSB static validator runs on the payload (same lexical surface) — any Critical finding blocks the write unless the operator set bypass_validator=true.
  3. Re-gate the FAP launch through the ConfirmSubtool hook. The Mousejack FAP starts an injection session the moment the operator presses OK on the Flipper; approving the workflow as a whole does NOT imply approval of the inject step.
  4. Launch the FAP via loader_nrf24mousejacker.

Risk is Critical: the flow culminates in keystroke injection at a paired host. Authorised lab / pentest use only.

Params:

  • name (string, required): payload filename (→ /ext/mousejacker/<name>.txt)
  • script (string, required): DuckyScript body
  • target_os (string, optional): windows | macos | linux (default windows)
  • max_delay_ms (int, optional): override the 5000 ms DELAY ceiling
  • addresses_path (string, optional): override the sniffer output path
  • bypass_validator (bool, optional): skip the block on critical static findings
  • launch (bool, optional): launch the FAP after writing. Default true.

func NFCBadgePipeline

func NFCBadgePipeline(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

NFCBadgePipeline triages an unknown NFC badge: nfc_detect → protocol classifier → protocol-specific follow-up. Returns a structured JSON report describing what the tag is and how to clone or attack it.

Risk is High: may launch dumping FAPs that can write to magic tags.

Params:

  • attempt_dump (bool, default false): launch protocol-appropriate dumping FAP after detection.
  • timeout_seconds (int, default 30): timeout for nfc_detect.

func PhysPentestBadgeWalk

func PhysPentestBadgeWalk(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

PhysPentestBadgeWalk loops RFID (LF 125 kHz) → NFC (HF 13.56 MHz) → iButton (1-Wire) reads until the caller's duration elapses or ctx is cancelled, dedupes captures by their decoded identifier, and mirrors every new sighting to a CSV on the Flipper's SD card.

Intended for a physical-pentest site walk: keep the Flipper in your pocket, run this workflow, and brush the reader against every badge/ fob/reader you encounter. The CSV is consumable by downstream tooling and the JSON report summarises unique badges seen.

Risk is Medium: read-only across three radios, but it writes a log file to SD.

Params:

  • duration_seconds (int, default 120, clamped 10..1800): total walk length.
  • per_read_timeout (int, default 3, clamped 1..15): per-radio read timeout.
  • csv_path (string, default /ext/badge_walk.csv): CSV output path.

func RolljamLabDemo

func RolljamLabDemo(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

RolljamLabDemo walks a lab-consented researcher through a two-capture rolljam sequence: prompt → RX capture #1 → prompt → RX capture #2. Both .sub files are retained on the SD card so the researcher can compare consecutive rolling-code transmissions and study the counter step at their leisure.

This workflow does NOT perform a real rolljam — a live rolljam requires simultaneous jam + capture on two separate radios, which the Flipper Zero's single CC1101 cannot do. It exists to stage the capture side of the attack under an authorised lab setting so the rolling-code math can be understood without ever transmitting.

Risk is Critical because the captures enable a real rolljam if paired with external jamming gear — we therefore hard-require lab_consent and refuse to run otherwise.

Params:

  • frequency (int, required): MHz in Hz (e.g. 433920000).
  • lab_consent (bool, REQUIRED true): explicit acknowledgement that this is authorised lab research. No default.
  • per_press_seconds (int, default 5, clamped 2..30): capture length per press.
  • output_dir (string, default /ext/subghz): SD card directory.

func WiFiTargetToHashcat

func WiFiTargetToHashcat(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

WiFiTargetToHashcat scans for nearby WPA/WPA2 APs, selects the strongest candidate (or a caller-supplied SSID), sniffs for a PMKID, and formats any capture into hashcat-22000 plaintext written to the Flipper SD card ready for offline cracking.

Requires a connected Marauder devboard — returns a structured refusal if deps.Marauder is nil.

Risk is High: active PMKID sniff plus a file write.

Params:

  • ssid (string, optional): target this SSID instead of auto-picking the strongest AP.
  • scan_seconds (int, default 10, clamped 3..60): AP scan window.
  • sniff_seconds (int, default 45, clamped 10..300): PMKID sniff window.
  • hashcat_path (string, default /ext/wifi/pmkid.22000): output path.

Types

type Deps

type Deps struct {
	Flipper      *flipper.Flipper
	Marauder     *marauder.Marauder // nil unless --wifi is active
	Vision       *vision.Analyzer   // may be nil in non-interactive surfaces
	Audit        *audit.Log         // nil when audit logging disabled
	Generator    *generate.Generator
	GenLLM       provider.Provider // raw LLM access for workflows that need ad-hoc summaries
	Capabilities flipper.Capabilities

	// ConfirmSubtool is an optional hook workflows call before
	// dispatching a High/Critical primitive internally. Returns true
	// to proceed, false to skip the sub-step. Nil disables the
	// additional gate (back-compat with tests and orchestrators that
	// already confirmed the workflow as a whole).
	//
	// Rationale: approving workflow_X once at the agent confirm gate
	// used to silently approve every destructive primitive the
	// workflow chained. This hook re-asks the operator for each such
	// sub-step so an approval of the composite doesn't imply an
	// approval of every radio transmission inside it.
	ConfirmSubtool func(ctx context.Context, tool string, input interface{}, riskLevel string) bool
}

Deps is the dependency surface workflows can call. Fields may be nil when the corresponding subsystem isn't connected; workflows that require a nil-able field MUST check and return a friendly error instead of panicking.

type NFCDetectInfo

type NFCDetectInfo struct {
	Protocol string
	UID      string
	ATQA     string
	SAK      string
	Family   NFCFamily
}

NFCDetectInfo is the parsed shape of an nfc_detect / NFC scanner output — enough for the pipeline to branch on family and echo key fields in the JSON result.

type NFCFamily

type NFCFamily int

NFCFamily is a coarse classification of the detected NFC tag. Drives the protocol-specific follow-up branch in NFCBadgePipeline.

const (
	NFCFamilyUnknown NFCFamily = iota
	NFCFamilyMIFAREClassic
	NFCFamilyUltralight
	NFCFamilyNTAG
	NFCFamilyDESFire
	NFCFamilyEMV
	NFCFamilyISO14443_4
)

type PhaseResult

type PhaseResult struct {
	Phase     string `json:"phase"`
	Tool      string `json:"tool"`
	Output    string `json:"output"`
	OK        bool   `json:"ok"`
	ElapsedMs int64  `json:"elapsed_ms"`
}

PhaseResult describes one orchestrated sub-step: the primitive called, whether it succeeded, how long it took, and the raw output string. The LLM reads these to reason about what happened mid-workflow.

type Result

type Result struct {
	Summary   string                 `json:"summary"`
	Phases    []PhaseResult          `json:"phases"`
	NextSteps []string               `json:"next_steps,omitempty"`
	Extra     map[string]interface{} `json:"-"`
}

Result is the JSON envelope every workflow returns. Workflow-specific fields live under Extra to keep the top-level shape stable across workflows while letting each one surface its own structured data (e.g. hashcat_format, i2c_addresses, pmkid_hex).

func (Result) MarshalJSON

func (r Result) MarshalJSON() ([]byte, error)

MarshalJSON merges Extra into the top-level object so the LLM sees a flat shape (e.g. "pmkid_hex" appears next to "summary", not under "extra.pmkid_hex"). Collisions with the stable fields are dropped in favour of the stable field.

type SubGHzDecodeInfo

type SubGHzDecodeInfo struct {
	Protocol string
	KeyHex   string
	Rolling  bool
}

SubGHzDecodeInfo is the parsed shape of `subghz decode_raw` output. Rolling is true for protocols whose decode output marks the key as rolling-code (KeeLoq, AES, Somfy Telis, etc.).

type Workflow

type Workflow func(ctx context.Context, deps Deps, params map[string]interface{}) (string, error)

Workflow is the common signature every composite implements. Params come straight from the LLM tool-call payload (map[string]interface{} decoded from JSON). The returned string is a JSON-encoded Result.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL