Documentation · v0.1.2

CableProbe documentation

Everything you need to run a session, tune it, and read the output. For installation see Download & install.

Concepts

A CableProbe session runs three phases in order:

PhaseWhat happens
baselineObserve the host before the unknown cable is connected.
testYou connect / power the unknown cable; CableProbe keeps observing.
post_testYou disconnect the cable; CableProbe observes the return to baseline.

CableProbe compares the three phases and writes a structured JSON report describing everything that appeared, disappeared or changed in correlation with the cable, then runs a set of YAML-configurable detection rules over those differences to produce prioritised findings.

Probes (observation only)

All 18 probes are enabled by default. Each one only reads host state. A probe whose interface the host does not expose (no Type-C class, no /sys/bus/pci, …) reports itself unavailable in cableprobe check and is skipped — that is not an error.

GroupProbeObserves
USB devices & topology usb USB device inventory: vendor/model, interface classes, HID, hubs.
usb_descriptors Per-interface USB descriptors from sysfs: class, subclass, driver, endpoints.
usb_topology The USB hub and port tree: hub count, device count, depth, per-hub inventory.
USB-C & Power Delivery usbc_pd USB-C / Power Delivery port and partner state: data and power roles, alternate modes.
Storage block Block devices (disks, partitions) and their transport.
mounts Filesystem mounts backed by a device or under removable-media paths.
Network network Network interfaces: driver, transport, USB-ness, addresses.
routing The default route and DNS resolvers — catches gateway or resolver hijack.
listeners TCP sockets in LISTEN state, with the owning process where available.
Peripherals input Input / HID devices: keyboards, mice, tablets.
serial Serial and modem (TTY) devices, including USB serial (CDC-ACM, FTDI, cp210x).
audio Audio (sound-card) devices, including the USB audio class.
video video4linux camera / capture devices, including UVC webcams.
System & kernel udev_monitor Live udev add/remove/change events across every subsystem, as they happen.
pci PCI and Thunderbolt devices — the USB4 / Thunderbolt PCIe-tunnel and DMA surface.
kernel_modules Loaded kernel modules — catches gadget drivers loaded on connect.
process Processes started after the session began.
kernel_log USB-relevant kernel and journal lines emitted during the session.

Commands

CommandPurpose
cableprobe checkVerify the host has what the enabled probes need.
cableprobe runRun a full baseline / test / post-test session and write a report.
cableprobe probesList the available probes.
cableprobe rules [FILE]Show the built-in detection rules, or validate a rules file.
cableprobe report FILEPrint a saved .cableprobe.json report (--format summary|json).
cableprobe --versionShow the version and exit.

run options

OptionMeaning
--baseline NBaseline phase duration in seconds.
--test NTest phase duration in seconds.
--post-test NPost-test phase duration in seconds.
--interval FSampling interval in seconds.
--config, -c FILEYAML config file.
--rules, -r FILEYAML rules file (default: built-in).
--output-dir, -o DIRWhere to write the report.
--name, -n NAMEHuman name for this session.
--autoDo not wait for operator input; advance phases on a timer.
--fail-on-findingsExit non-zero when medium+ findings are present.
--verbose, -v-v info, -vv debug.

Usage

# Check the host is ready
cableprobe check

# Run a session (you will be prompted before each phase)
sudo cableprobe run --name "suspect-cable-01" \
    --baseline 30 --test 90 --post-test 30

# Unattended / rig mode: advance phases on a timer instead of prompts
sudo cableprobe run --auto --baseline 20 --test 60 --post-test 20

# Inspect a saved report
cableprobe report cableprobe-sessions/2026*.cableprobe.json
cableprobe report <file> --format json | jq .

# See / customise detection rules
cableprobe rules
cableprobe rules my-rules.yaml

Running with sudo is recommended: the kernel-log and udev-attribute probes see more detail with privileges.

Exit codes

cableprobe run --fail-on-findings exits 10 / 20 / 30 for the highest finding severity (medium / high / critical), otherwise 0. Without the flag, run always exits 0 on a completed session.

Configuration

Optional YAML config, passed with --config cableprobe.yaml. probes.enabled defaults to the full list below; trim it to run fewer.

session:
  baseline_seconds: 30
  test_seconds: 90
  post_test_seconds: 30
  sample_interval_seconds: 2.0
probes:
  enabled: [udev_monitor, usb, usb_descriptors, usb_topology, usbc_pd, block,
            mounts, network, routing, listeners, input, serial, audio, video, pci,
            kernel_modules, process, kernel_log]
  kernel_log_backend: auto      # auto | journalctl | dmesg
  kernel_log_keywords: []       # extra case-insensitive substrings to keep
rules_file: null                # null => packaged default rules
output_dir: ./cableprobe-sessions

Detection rules

Rules live in YAML (see cableprobe/data/default_rules.yaml). Each rule matches a phase delta and raises a finding:

- id: hid-keyboard-appeared-on-connect
  title: HID keyboard appeared while the unknown cable was connected
  severity: high
  rationale: >
    A keyboard-class HID device that enumerates only when the cable is
    connected is the classic BadUSB signature.
  match:
    change: appeared          # appeared | disappeared | modified
    first_seen_phase: test    # baseline | test | post_test
    kind: [input_device, hid_device]
    attributes:
      any:
        - { key: ID_INPUT_KEYBOARD, equals: "1" }

Match keys: change, kind, first_seen_phase, reverted_after_disconnect, transient, label_regex, event_action, and attributes.all / attributes.any (conditions: equals, not_equals, exists, contains, regex).

Severities: info, low, medium, high, critical.

Report structure

{
  "metadata":  { "session_name", "host", "config", "probes_used", "probe_warnings", ... },
  "phases":    { "baseline": {...}, "test": {...}, "post_test": {...} },
  "deltas":    [ { "change", "kind", "identity", "label",
                   "first_seen_phase", "present_in",
                   "reverted_after_disconnect", "transient",
                   "attributes", "attribute_changes", "related_events" } ],
  "findings":  [ { "rule_id", "title", "severity", "rationale", "evidence" } ],
  "summary":   { "delta_count", "cable_correlated_change_count",
                 "findings_by_severity", "highest_severity", ... }
}

Third-party dependencies

CableProbe does not copy or vendor third-party source code. It depends on a small set of Python libraries and, at runtime, invokes standard Linux command-line tools as separate, independently installed programs.

PackageLicenceNotes
typerMITCLI framework
pydanticMITdata models
psutilBSD-3-Clauseprocess / network inventory
PyYAMLMITconfig and rules parsing
richMITconsole rendering
pyudevLGPL-2.1-or-laterLinux-only; imported as a library, not vendored or modified
pytest, pytest-asyncioMIT, Apache-2.0dev only

Note on pyudev: it is a normal, separately installed dependency that CableProbe imports; it is not vendored or modified. If you redistribute CableProbe as a bundled binary/image, keep pyudev as a replaceable component and include its licence text. The Linux CLI tools CableProbe shells out to (lsusb/usbutils, lsblk/dmesg/util-linux, journalctl/systemd) are invoked as independent programs and do not affect CableProbe's MIT licensing.

Scope & non-goals

  • CLI only — no web dashboard.
  • The usbc_pd probe reads the kernel's USB-C / Power Delivery port state (roles, alternate modes); CableProbe does not do electrical measurement of the cable itself (voltage, current, e-marker interrogation).
  • No offensive capability of any kind, by design.

See Contributing for how to propose changes, and Security & trust for how to report vulnerabilities privately.