Quattro Vision
Reverse Engineering Industrial Gas Detector Firmware
Industrial gas detectors protect workers in hazardous environments, but their firmware security remains largely unexplored. This research documents the complete reverse engineering process for the BW Technologies Quattro, from proprietary container extraction through XOR decryption to ARM Thumb disassembly.
Gas detectors are the last line of defence in confined spaces, mines, and chemical plants. We opened one up — not the hardware, but the firmware — and what we found was both fascinating and concerning.
The device nobody questions
The BW Technologies Quattro is unremarkable by design. A yellow plastic brick, roughly the size of a pager, clipped to the belt of every worker who enters a confined space. It monitors four gases simultaneously — hydrogen sulphide, carbon monoxide, oxygen levels, and combustible gases — and screams when any of them exceed safe limits. In mining, petrochemical, and wastewater industries, it’s as standard as a hard hat.
The detection is not the question. What runs underneath it is.
Like most industrial safety equipment, the Quattro’s firmware has never been publicly analysed. The assumption — reasonable on its surface — is that safety-critical devices have robust security. The device works. People trust it. Nobody looks inside.
Nobody had looked. The firmware had never been publicly analysed.
Cracking the container
The Quattro’s firmware ships in a proprietary format called RFP — Remote Firmware Package. Firmware updates are distributed through Honeywell’s Fleet Manager software, a Java application that handles device management over USB.
The RFP file turns out to be a 907-byte proprietary header followed by a standard ZIP archive. The header contains device identification, version metadata, and integrity checks. The ZIP contains two binaries: gaqmf_bootloadable.bin (main firmware) and gaqsf_bootloadable.bin (sensor firmware).
┌──────────────────────────────┐ │ Proprietary Header (907B) │ Device ID, version, checksums ├──────────────────────────────┤ │ Standard ZIP Archive │ │ ├─ gaqmf_bootloadable.bin │ Main firmware (ARM Thumb) │ └─ gaqsf_bootloadable.bin │ Sensor firmware └──────────────────────────────┘ Each bootloadable binary: ┌──────────────────────────────┐ 0x000 │ Boot Header (64 bytes) │ Magic: _Bo0t_GAQF │ Version, build timestamp │ ├──────────────────────────────┤ 0x040 │ Alignment Padding (960B) │ Null bytes ├──────────────────────────────┤ 0x400 │ Encrypted Payload │ XOR cipher, ARM Thumb code │ (remainder of file) │ └──────────────────────────────┘
The magic bytes _Bo0t_GAQF identify the firmware type. The 960-byte null padding aligns the code payload to a 1024-byte boundary — a requirement of the AT91SAM7S256 microcontroller’s flash memory architecture.
The Wolverine key
The key is recoverable without touching the device.
Decompiling the Fleet Manager’s Java bytecode revealed a file called SecurityModel.java. Inside it: a reference to something called “Wolverine” and a key derivation routine tied to the default administrator password “Admin.”
The encryption protecting the firmware — code that runs on a device responsible for keeping people alive in toxic atmospheres — is a repeating XOR cipher with a static 8-byte key.
Key derivation: Fleet Manager → SecurityModel.java → "Wolverine" reference Default password: "Admin" Derived XOR key: B2 B5 5E CF A0 CE 81 21 Properties: Algorithm .......... Repeating XOR (symmetric) Key length ......... 8 bytes Payload offset ..... 0x400 from file start Key rotation ....... None (static) Salt ............... None Code signing ....... None
To put this in perspective: the same encryption approach was considered weak in the 1990s. XOR with a short, static, derivable key provides effectively no protection against anyone willing to decompile a Java application. The firmware can be decrypted, modified, and re-encrypted with the same key.
There is no code signing. No integrity verification beyond the container header. If you can modify the firmware and flash it over USB using Atmel’s documented SAM-BA protocol, the device will run whatever you give it.
Inside the ARM
The decrypted payload is ARM Thumb code targeting the AT91SAM7S256 — a 55 MHz ARM7TDMI microcontroller with 256 KB of flash and 64 KB of SRAM. This is a mature, well-documented chip family. Ghidra handles it capably.
Processor .......... AT91SAM7S256 (Atmel / Microchip) Core ............... ARM7TDMI Architecture ....... ARMv4T Instruction set .... ARM (32-bit) + Thumb (16-bit) Flash .............. 256 KB SRAM ............... 64 KB Clock .............. 55 MHz Programming ........ USB via SAM-BA bootloader Memory Map: 0x00000000 ─ 0x0003FFFF Flash (256 KB) 0x00200000 ─ 0x0020FFFF SRAM (64 KB) 0xFFFFF000 ─ 0xFFFFFFFF Peripheral registers
The firmware operates primarily in Thumb mode for code density — a common choice on memory-constrained ARM7 devices. The vector table at address zero provides the expected entry points: reset handler, undefined instruction, software interrupt, prefetch abort, data abort, and IRQ/FIQ handlers.
Static analysis in Ghidra has begun mapping the firmware’s functional regions. Display initialisation routines, gas sensor calibration loops, and alarm threshold logic are identifiable through cross-referencing string constants and peripheral register accesses.
The analysis pipeline
The research produced a reproducible three-stage pipeline, documented with Kaitai Struct format definitions for the proprietary binary structures:
Stage 1: Container Extraction ──────────────────────────────────── Input: firmware.rfp Process: Strip 907B header → Extract ZIP → Isolate bootloadables Output: gaqmf_bootloadable.bin, metadata.json Stage 2: Payload Carving ──────────────────────────────────── Input: gaqmf_bootloadable.bin Process: Parse _Bo0t_ header → Skip padding → Extract payload Output: encrypted_payload.bin, header_info.json Stage 3: Decryption ──────────────────────────────────── Input: encrypted_payload.bin Process: Apply XOR key (B2 B5 5E CF A0 CE 81 21) Output: decrypted_arm_thumb.bin → Load into Ghidra
Every step is scripted in Python with documented dependencies. The Kaitai Struct definitions make the binary formats self-documenting — anyone can parse these files without reading the analysis code.
What this means
The Quattro is not unique. It represents a class of industrial IoT devices where firmware security was never a design priority. The economics of embedded development — particularly in safety equipment designed in the mid-2000s — favoured simplicity over security. XOR encryption was “good enough” when the threat model assumed physical access was the only attack vector.
That assumption hasn’t aged well. Fleet management systems connect these devices to networks. Firmware updates travel over USB from internet-connected PCs. The attack surface has expanded while the security model hasn’t.
Security findings, as at December 2024
| Observation | Severity | Status |
|---|---|---|
| XOR cipher with static key | Critical | Confirmed |
| No firmware code signing | Critical | Confirmed |
| Keys derivable from vendor SW | High | Confirmed |
| Standard USB flash protocol | Medium | Confirmed |
| No rollback protection | Medium | Confirmed |
✓ Firmware extraction complete ✓ Decryption key identified ✓ ARM Thumb disassembly loaded ◎ Display routine analysis in progress ○ Custom firmware POC pending ○ USB flash protocol documentation pending
The question this was run to answer is whether the security posture of safety-critical industrial devices matches the trust placed in them.
On the evidence here, it does not: two critical findings, both confirmed, in a device relied on to keep people alive.
This research is conducted for educational and security research purposes. Gas detector safety functionality should never be modified in production devices. Contact research@drksci.com for responsible disclosure inquiries.