No mitigations, full code execution
Memory corruption in shared embedded firmware components grants attacker code execution at firmware privilege, replicated across hundreds of vendor devices.
SubQ 1.1 is not a CVE. It is a capability demonstration. Arbitrary code execution inside the firmware of an embedded device, reached through memory corruption, with the attacker holding the program counter from first overflow to final payload. The interesting part is not the bug. It is what the bug proves about a class of targets that ship without the mitigations every desktop has had for fifteen years.
Start with the target. An embedded device here means a microcontroller or system-on-chip running a real-time operating system or a bare-metal firmware image. Cortex-M, MIPS, older ARM9. Flat physical memory. Frequently no memory management unit. The firmware is a single image. Code, data, stack, and heap share one address space with no privilege separation between the network stack and the routine that toggles a relay.
The bug class is classic linear memory corruption. Stack-based buffer overflow. Heap overflow. Off-by-one in a length calculation. The reason these still produce reliable code execution on embedded targets, when the same bug on a modern Linux host is a hardened crash, is the absence of mitigations. No ASLR, because there is no loader randomising base addresses. No DEP or W^X, because there is no MMU to mark pages non-executable. Stack canaries are a compiler flag that vendors disable for size or speed. The result is a memory model from 1999 reachable over the network in 2026.
Walk the mechanism. A network-facing parser reads an attacker-supplied field. A length value, a TLV record, a hostname in a DHCP option. The code copies that field into a fixed stack buffer without validating the supplied length against the destination size. The copy runs past the buffer, over the saved registers, over the saved return address. When the function returns, the program counter loads a value the attacker wrote. Because memory is not randomised, the attacker knows where the firmware’s own code lives. Because the stack is executable in many builds, return-oriented programming is optional. The payload runs where it landed.
The heap variant is the same failure with a longer fuse. An allocator on an embedded target is often a simple free-list with inline metadata. An overflow past a heap buffer corrupts the size and pointer fields of the adjacent chunk header. On the next allocation or free, the allocator follows the attacker-controlled pointer and performs a write. That write, placed against a function pointer table or an RTOS task control block, converts heap corruption into control of execution. BadAlloc was exactly this. Integer overflow in the size argument to an allocation call, undersized buffer returned, linear overflow on use.
The exploit path is shorter than on any general-purpose OS. No sandbox to escape. No second primitive to chain. On a desktop browser, renderer code execution is the start of the work, not the end, because the sandbox stands between the renderer and the host. On a flat embedded image, the first reliable control of the program counter is the objective. Code execution in the parser is code execution in the firmware, with whatever hardware privilege the firmware holds. Read the flash. Write the flash. Drive the peripherals. Pivot to the internal network the device sits on.
What the attacker controls is the layout, and the layout is static. Same firmware version, same memory map, on every unit shipped. An exploit developed against one device works against every device running that image. This is the property that turns a single bug into a fleet compromise.
This is where it stops being theory. The shared component is the multiplier. Embedded vendors do not write their own TCP/IP stacks. They license one. They do not write their own RTOS network services. They integrate an SDK. When the bug lives in that shared component, it ships into hundreds of unrelated products under hundreds of brand names, and most of those vendors do not know which third-party code is inside their own firmware.
The record is explicit. Ripple20, 2020, was nineteen vulnerabilities in the Treck TCP/IP stack. CVE-2020-11896 carried a CVSS v3 base of 10.0, remote code execution from a crafted IPv4 packet. The Treck stack was embedded in printers, infusion pumps, industrial controllers, and power equipment across hundreds of vendors. URGENT/11, 2019, was eleven flaws in the IPnet stack used by VxWorks. CVE-2019-12256, CVSS 9.8, stack overflow in IPv4 options parsing. BadAlloc, 2021, was a set of integer-overflow-to-heap-overflow bugs across multiple RTOS and memory allocators. CVE-2021-35394, CVSS 9.8, remote code execution in the Realtek Jungle SDK, weaponised into botnet worming within weeks of disclosure.
The visibility problem compounds the bug. A software bill of materials for firmware is rare. The device vendor frequently cannot enumerate the third-party stacks, SDKs, and libraries inside the image they ship, because the integration happened through a chip vendor’s reference design two or three tiers up the chain. When a Treck or IPnet advisory lands, the question ‘are we affected’ has no fast answer. The component is present, but no manifest records it. Identification proceeds by binary analysis, vendor inquiry, or the device behaving badly in the field.
Each of these is SubQ 1.1 with a serial number. A memory corruption bug in a component the device vendor did not write, reachable over the network, granting code execution at firmware privilege, replicated across a supply chain the buyer never had visibility into. The capability is constant. The CVE number is just which component shipped it this time.
The attacker mapping is ATT&CK T1190, exploitation of a public-facing application or service, against the network-facing parser. For network devices, follow-on activity maps to T1542 pre-OS boot persistence and T1601 system image modification, because firmware-level code can rewrite the image that loads on next boot. In industrial environments the relevant techniques sit in the ATT&CK for ICS matrix, T0839 module firmware and T0857 system firmware, where the device is the objective rather than a stepping stone.
Now the part defenders do not want to hear. The telemetry is close to nothing.
There is no EDR agent on a Cortex-M microcontroller. There is no Sysmon. There is no process creation event, because there is no process model. The firmware that executes the attacker’s payload is the same firmware that executes the legitimate code, in the same address space, under the same single thread of control. No new process spawns. No new module loads. No event ID fires because nothing is emitting events.
What remains is the network. The exploitation packet itself may be visible in a full capture, but only if a sensor sits inline on the segment where the device lives, and embedded devices are usually on the segments least instrumented. The reliable signal is post-exploitation behaviour. A device that has never initiated an outbound connection suddenly beacons. A printer reaching a host in another country. A controller scanning its own subnet. These are NetFlow and network metadata observations, not endpoint detections, and they fire after code execution, not before.
Detection that works here is network-anchored and behavioural. Baseline the connection profile of each embedded device class. A given model talks to a known set of peers on a known set of ports. Deviation from that profile - new destinations, new ports, outbound volume on a device that only ever received - is the detectable event. Passive asset inventory feeds it. Network metadata, not endpoint logs, carries the signal. The detection fires on consequence, because the cause is invisible, and a detection on consequence still beats the alternative, which is discovery during incident response.
The gap is structural. Defender visibility ends at the network port of the device. Everything that happens inside the firmware is dark. There is no log to correlate, no telemetry to baseline, no agent to query. The compromise is inferred from what the device does on the wire, or it is not seen at all. For a device whose job is to talk on the wire, that inference is hard.
The patch boundary is where the residual exposure becomes obvious. A fix for a bug in a shared stack means the component author ships a corrected version. Then every downstream vendor has to integrate it, rebuild the firmware image, test it, and push it to deployed units that often have no automatic update path. For the named cases, patched component versions existed within weeks. Vulnerable firmware built on the old versions remained in production for years. Some of it still is. The CVE is closed. The devices are not.
What still applies after patch is the model. The mitigations that make a memory corruption bug survivable on a modern host - randomised layout, non-executable memory, stack integrity checks, privilege separation - are absent or optional on most embedded targets by default. Until the compiler flags are on and the hardware features are used, the next bug in the next shared component produces the same outcome as the last one. Direct control of the program counter, code execution at firmware privilege, replicated across every unit that shipped the same image.
For operators inside scope of the Security of Critical Infrastructure regime, the embedded device is frequently the asset the obligations attach to, and the one with the least instrumentation. Suspected firmware compromise on those assets is an escalation to the asset owner’s security function and the relevant national CERT, not a problem to triage in isolation.
SubQ 1.1 is the demonstration. The supply chain is the distribution mechanism. The absence of telemetry is why it works longer than it should.
Keep Reading
game securityStop Killing Games guarantees unpatched network-reachable code
Stop Killing Games is preservation law, not a security control. Statute governs publishers; it never patches the memory-corruption bugs attackers exploit.
game securityRing 0, fed a stranger's save file
The US directive suspending Fable 5 and Mythos 5, analyzed: why game clients are privileged code, how asset and netcode bugs work, and why trust is the flaw.
IOCCC 2025IOCCC 2025 ships glibc tcache poisoning primitives
The 29th IOCCC's 2025 winners distill heap metadata corruption, tcache poisoning, and type confusion into legal C - the same primitives behind modern CVEs.
Stay in the loop
New writing delivered when it's ready. No schedule, no spam.