· 5 min read ·

The Blob Was Never Doing Anything Complicated

Source: lobsters

There is a recurring pattern in embedded and laptop hardware where vendors ship a binary blob to perform some initialization task, and the implication is that this task is too complex or too sensitive to be done any other way. Then someone reads the serial traffic with strace or a terminal emulator and finds out the blob was just sending three AT commands to a modem.

That is essentially what happened when a developer published a post showing how they replaced Lenovo’s WWAN unlock binary with a ~100-line Bash script. The script does the same job. The blob is gone.

What the Allowlist Actually Does

Lenovo ThinkPads have enforced hardware allowlists since at least the mid-2000s. The original mechanism was straightforward and brutal: if you booted with a WWAN or WLAN card that wasn’t on Lenovo’s approved list, the BIOS would refuse to boot and display error 1802: Unauthorized network card is plugged in. The list lived in the firmware image itself, and the ThinkPad community spent years hex-patching BIOS images to remove it.

On newer machines, the mechanism shifted. Instead of a hard BIOS block, some ThinkPads ship WWAN cards that are installed but not activated. The modem is physically present, recognized over USB, and has its firmware loaded, but it won’t register on any network. Something has to tell the modem it’s allowed to operate in this particular laptop. That something was, until recently, a binary.

The unlock payload typically arrives through one of two channels. On Windows, Lenovo’s software suite handles it transparently. On Linux, the fwupd project and the Linux Vendor Firmware Service (LVFS) carry a lot of Lenovo’s firmware updates, and Lenovo has used this infrastructure to ship both modem firmware and ancillary unlock tooling. Either way, the user sees a black box that runs once and enables their hardware.

What AT Commands Actually Are

The Hayes AT command set was designed in 1981 for the Smartmodem 300. It has survived, in extended and vendor-augmented form, in virtually every cellular modem sold today. A command looks like this:

AT+CGDCONT=1,"IP","internet.provider.net"

You open a serial device, write ASCII strings, and read ASCII responses. The modem replies OK or ERROR or data. That is the entire protocol for a large fraction of modem configuration, including the kind of per-device provisioning that Lenovo’s unlock step was doing.

On Linux, WWAN cards typically expose multiple USB interfaces. One of these is a serial AT command port, often appearing as /dev/ttyUSB2 or a similarly numbered device. ModemManager, the standard Linux daemon for managing cellular modems, talks to this port. So does mmcli, its command-line interface. So does minicom, screen, or any program that can open a serial device and write text.

# Send an AT command directly to the modem's serial interface
exec 3<>/dev/ttyUSB2
echo -e 'AT+COMMAND\r' >&3
read -t 2 response <&3
exec 3>&-

This is essentially the skeleton of what the Bash script replacement does, wrapped in some error handling and response parsing. The unlock operation involves sending specific vendor commands to the modem, which stores the result in its non-volatile memory. After that, the modem behaves as fully operational on subsequent boots.

What Reverse Engineering the Blob Requires

Figuring out what the binary was doing is not especially difficult on Linux. strace will show every system call the binary makes, including open() calls on serial devices and write() calls with the command strings. usbmon or Wireshark with the usbmon capture backend will show the raw USB transfers at the transport level. If the blob communicates with the modem over a serial interface, the commands it sends are plaintext.

Vendors are aware of this. The blob’s opacity is not a technical property; it is a policy choice. The same unlock could have been shipped as a documented script from the beginning. The decision to ship a binary is a decision to maintain control over the provisioning process, not a decision forced by any technical constraint.

This matters because blobs that run as root to configure hardware are a meaningful attack surface. A signed, auditable script can be verified against its source. A binary that ships through an update channel, runs as root, and touches hardware interfaces cannot be audited in the same way. Replacing it with readable code is a genuine security improvement, not just a philosophical preference.

The Fibocom and Sierra Wireless Ecosystem

Most recent ThinkPads use WWAN cards from Fibocom (like the L850-GL or FM350-GL) or Sierra Wireless (like the EM7455 or EM7565). Both vendors have their own AT command extensions on top of the standard set.

Sierra Wireless modems use commands prefixed with AT! for proprietary configuration. AT!ENTERCND puts the modem into a configuration mode. AT!CUSTOM reads and writes named configuration parameters. The specific commands needed to enable a modem for a given carrier band configuration or unlock a device-level restriction are documented in Sierra’s AT command reference, which is publicly available to anyone who registers on their developer portal.

Fibocom modems have similar structures. The Fibocom L850-GL, which ships in several ThinkPad X1 and T-series machines, uses Intel’s XMM7560 modem chipset, and its AT command set reflects that heritage. The commands used to configure USB composition (which USB interfaces the modem exposes) follow the AT+GTUSBCOMP pattern from the Intel modem documentation.

The point is that the information required to write the Bash script was never secret. It was in vendor documentation, community wikis, and ModemManager’s source code. The blob added nothing except obscurity.

ModemManager’s Role

One thing worth noting: on an active Linux system, ModemManager will probe and potentially manage the modem before you can interact with it directly. If you try to open the AT command port while ModemManager has it locked, your write will fail or produce no response.

The standard approach is to either stop ModemManager temporarily, or use mmcli to send arbitrary AT commands through ModemManager’s own interface:

# List modems
mmcli -L

# Send AT command via ModemManager (modem index from -L output)
mmcli -m 0 --command='AT+CGMR'

A well-written replacement script handles this by detecting ModemManager’s state and either working through it or temporarily stopping it, then restarting it afterward. This is one of the reasons the script needs ~100 lines rather than ten: the plumbing around the actual commands is more work than the commands themselves.

The Broader Point About Blobs

This situation is not unique to Lenovo or to WWAN. Binary blobs appear throughout the hardware stack: firmware for embedded controllers, initialization sequences for display panels, calibration payloads for sensors. In most cases, these blobs perform operations that are describable in plain terms, and the decision to ship them as binaries reflects vendor preference rather than any requirement.

The Linux kernel’s long-running tension with proprietary firmware blobs, the work of the linux-firmware repository maintainers, and projects like coreboot and libreboot all reflect the same fundamental observation: the blob represents a trust boundary that the user did not ask for and cannot meaningfully inspect.

When someone takes the time to replace a blob with a readable script, they are not just solving a practical problem for themselves. They are demonstrating that the boundary was always negotiable, and they are giving the next person a starting point. That is how a lot of Linux hardware support gets built: one person does the work of reading the traffic and writing it down, and the community inherits something auditable and maintainable.

The 100-line Bash script is not particularly impressive as a piece of code. What it represents is worth more than the code itself.

Was this interesting?