alosafuzz
ICS/OT protocol security research — fuzzing, scanning, and coordinated disclosure.

A Researcher's Guide to SCPI & LXI Test Instruments

Vendor: cross · Sector: iiot, cross · Transport: raw-socket, vxi-11, hislip · Project: fieldbusfuzzer

Part of the alosafuzz ICS protocol-guide series — written for fuzzing and vulnerability researchers. Defensive posture: wire format, fuzz surface, and published bug classes only; no weaponized exploit or DoS code.


1. What it is & where it runs

SCPI (Standard Commands for Programmable Instruments, SCPI-99, layered on IEEE-488.2) is the text command language spoken by bench and rack test & measurement gear — oscilloscopes, DMMs, spectrum/logic analyzers, power supplies, signal generators, source-measure units. It shows up in RF/EW labs, power and calibration labs, semiconductor test, and increasingly on automated production lines wired into the plant network — a scope-expansion for an ICS fuzzer, the test-instrument/IIoT neighbor of OPC-UA’s IT-ward lean, not a classic floor bus.

The single most important finding for a researcher: “GPIB” is largely a red herring for a network fuzzer. Raw GPIB/IEEE-488 is a parallel hardware bus (needs a controller card) — not reachable over IP. Modern instruments carry SCPI over LAN (the LXI standard), and that is the attack surface. And across all three LAN transports, the bytes converge on one place: the instrument’s SCPI command parser. A “SCPI fuzzer” is overwhelmingly a command-parser fuzzer plus thin transport framing — exactly where the public CVE record lands (§5).

2. Session & transport model

Three transports, three framings, one SCPI semantic core:

3. Wire format — SCPI (the real target)

SCPI is line-oriented ASCII, newline-terminated, but the parser is richer than it looks — and the parameter grammar is where the length/overrun bugs live.

VXI-11 framing sub-surface: ONC-RPC fragment/record marking (the continuation bit + 31-bit length), create_link/device_write/device_read argument structs (link IDs, flags, lengths), and portmapper GETPORT. HiSLIP framing sub-surface: the fixed 16-byte message header, especially the 64-bit payload length field vs. bytes delivered, message-type/control-code enums, and the two-socket sync/async correlation.

4. The fuzz surface

Classification line: a SCPI error pushed onto the Standard Event Status / error queue (e.g. -113 "Undefined header", -108 "Parameter not allowed"), or a VXI-11/HiSLIP protocol error reply, is a spec-compliant exception, not a crash. A dropped/hung connection is only a crash if a liveness re-probe also fails (§6).

Structured vs. coverage-guided: both. The one broadly-reused open-source parser, j123b567/scpi-parser (libscpi), is an ideal coverage-guided/ASan target — in-process, deterministic, no hardware, and transport-agnostic (the parsed string is identical whether it arrived via raw-5025, VXI-11, or HiSLIP). The raw-socket (5025) wire rig and the VXI-11/HiSLIP framing are the structured black-box niche against real (closed) instrument firmware, which is exactly where the Siglent product CVEs landed.

5. Known vulnerabilities & bug classes (verified)

Every confirmed bug sits in a surface §3/§4 names in advance:

6. Building a test harness

Two complementary rigs, mirroring the suite’s coverage-guided + wire-reachability pattern:

Harness lessons that generalize (from the suite):

7. Open-source implementations & tooling

8. Spec references & sources

9. Open questions / under-explored surface

This guide is written from the 2026-10-08 GPIB/SCPI gap survey (fieldbus-fuzzer/lab-notes/scpi-gpib-gap-survey.md) — forward-looking, ahead of a worked module. The recommended first build is a libscpi coverage-guided target (SCPI_Input/SCPI_Parse under libFuzzer+ASan) with a raw-socket (TCP 5025) wire-reachability rig; libscpi API signatures above verified against upstream parser.h.