2026-09-28
The skeleton key in cab_meshd
An unauthenticated attacker on the router's Wi-Fi obtains an interactive root shell — no credentials, no user interaction, no WAN cable. Two vulnerabilities in the Xiaomi mesh daemon cab_meshd chain together: the first leaks the router's admin login verifier via a hard-coded, firmware-global key; the resulting admin session then plants a command-injection payload into a Wi-Fi config field that a root shell eval executes. The device stays online throughout. Confirmed end-to-end on physical hardware.
The hard-coded key is not specific to one device. It is byte-identical in the stock firmware of 28 Xiaomi and Redmi router model codes, spanning three CPU architectures and three Wi-Fi generations — from a sub-$25 Wi-Fi 5 box to the current BE10000 flagship. It is unpatched as of publication.
Status: Unpatched — no fix, fix plan, or timeline committed by the vendor. Reported: 2026-08-14 to Xiaomi; with CERT/CC via VINCE (
VRF#26-09-SFWHW). Published: 2026-09-28. The full advisory, technical appendix, cross-model evidence, and proof-of-concept are in the repository, or as a downloadable archive (offline mirror).
In one paragraph
Xiaomi routers form mesh networks by talking to each other on TCP/UDP port 19553, handled by a background daemon named cab_meshd. To prove a peer is "a real Xiaomi router," the daemon checks a message signed with a secret key — but that key is compiled into the firmware and is identical on every unit, so it is not a secret at all. Anyone can read it out of a firmware image and sign the message themselves. Once past that check, the router hands its own admin-login verifier to the peer (V1 — admin takeover), and that admin session can plant a booby-trapped value into a Wi-Fi setting that a root script later runs through eval (V2 — root command execution).
The exploit at a glance
Affected product
| Analysed device | Xiaomi Router AX3000T (xiaomi.router.rd03v2, hardware RD03v2) |
| Firmware | MiWiFi / XiaoQiang romversion 2.0.28 (analysed and tested) |
| Component | /usr/sbin/cab_meshd (mesh commissioning daemon) |
| Exposure | TCP/UDP 19553 on the LAN bridge (br-lan) once the device is initialised — the normal state of a router in use |
The daemon listens on the LAN bridge, not the WAN, so this is not directly exploitable from the internet. The entire prerequisite is being on the same layer-2 network: home Wi-Fi, a bridged guest network, or a wired port. No credentials, no user interaction, no physical access.
The two vulnerabilities
V1 — unauthenticated admin-credential disclosure → takeover
An attacker who can reach port 19553 completes the mesh handshake using the hard-coded, firmware-global HMAC key — no per-device secret, no client certificate (the TLS server sets SSL_VERIFY_NONE, so it accepts any client). Completing the handshake drives the daemon to its ST_RUNNING state, and on that transition the router transmits its own web-admin login verifier (web_passwd256, the exact SHA-256 the web login checks) to the peer inside the config-sync message. The attacker computes sha256(nonce ‖ web_passwd256) and logs into the web UI as admin.
- No password guessing, no memory corruption, no user interaction. It fires the moment
ST_RUNNINGis reached. - Confirmed end-to-end on physical hardware (leaked the verifier, minted a valid admin session, read back real admin data).
- CWEs: CWE-798 (hard-coded key), CWE-295 (improper certificate validation), CWE-522 / CWE-200 (exposure of the credential verifier to a peer).
- CVSS 3.1:
AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H→ 8.8 (High).
Full admin over the router is itself total compromise: rewrite DNS to intercept traffic, open WAN management and port-forwards, disable the firewall, read Wi-Fi and guest passwords, and pivot to LAN devices. Because the key is identical across units, a single extraction is weaponisable fleet-wide.
V2 — unauthenticated OS command execution as root
The same cap_init handler the handshake reaches also accepts attacker-controlled Wi-Fi configuration values planted via the admin API. Chaining V1 into V2 yields a full over-the-air root RCE with an interactive root shell — confirmed end-to-end on physical hardware.
- V1 leaks
web_passwd256over Wi-Fi and mints an admin session. - The admin API plants command-injection payloads into the
encryptionUCI keys for the 2.4 GHz and 5 GHz bands. These fields are exempt fromhackCheck, the web input sanitiser that blocks; | $ &, so shell metacharacters pass through. The SSID is preserved, so nothing looks different. - A
type-4→5→7trigger firescap_init. Inside it,mgmt_2g=$(uci get wireless.<iface>.encryption)reads the poisoned value raw and passes it into aneval. - The injected payload breaks out of the quoting and runs as root. A downloaded stager calls back (
uid=0), self-repairs the Wi-Fi so the AP stays online, and opens a persistent reverse shell.
- CWE-78 (OS command injection). CVSS 3.1:
AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H→ 8.8 (High). - Confirmed on physical hardware: root callback
uid=0_user=root_host=XiaoQiang, interactive BusyBoxashroot shell, full device enumeration. The device stays online throughout.
How far it reaches
Stock firmware was downloaded for 29 model codes — mostly straight from Xiaomi's own CDN — and searched for the key. 28 of 28 obtainable images contain it. Zero exceptions. One code (RD13, Mesh System AC1200) has no obtainable image and is unconfirmed rather than negative.
| Breakdown | Count |
|---|---|
| ARM64 (aarch64) models | 13 |
| ARM32 (EABI5) models | 13 |
| MIPS32el models | 2 |
| Wi-Fi 5 | 1 |
| Wi-Fi 6 | 20 |
| Wi-Fi 7 | 7 |
The affected set spans currently-shipping Wi-Fi 7 flagships (BE10000, BE6500 Pro) down to the mass-market Mi Router 4A Gigabit Edition — a MIPS, Wi-Fi 5, sub-$25 device from a much higher-volume era, and one of the few Xiaomi router lines sold in volume outside China. Any estimate built on "Wi-Fi 6 and newer only" is a floor, not a central figure.
A per-model patch does not resolve this. Because the key is shared for cross-model mesh compatibility, any model left on the old key keeps it valid against every other. The fix has to be architectural — retire the global key, move to a per-device secret, and require real certificate checks. Some affected lines also appear to have no update channel at all.
Two evidentiary notes, stated plainly:
- V1 applies across all 28 confirmed model codes. On each, the key is present and is the only long hex literal in
cab_meshd; the binary carries the same protocol and state machine; and the init script gates the listener identically. The full chain was executed on hardware onRD03v2/2.0.28; on the others it rests on that identity of key, daemon, and start condition. - V2 is confirmed end-to-end only on
RD03v2/2.0.28. Its two components (theevalsink and the rawencryptionread that feeds it) are present across generations, but two links — whether other firmwares' admin API exemptsencryptionfromhackCheck, and whether the payload survives their quoting identically — were not verified elsewhere. So: the sink and its input path are present across the line; the full chain is demonstrated onRD03v22.0.28only.
How this was found
The discovery was an AI-assisted reverse-engineering effort: a set of language-model agents hunting for candidate vulnerabilities in parallel, with the findings put through repeated adversarial review, and every surviving claim confirmed by hand on real hardware. The method matters here because it produced both a false positive that was caught and a real result that a first pass had wrongly dismissed.
1. Getting to analyzable code. Starting from the signed stock 2.0.28 image, the firmware was unpacked (HDR1 container → UBI → SquashFS) and run under user-mode emulation. All 253 compiled Lua chunks were decompiled to source, and disassembly "ground truth" was produced with the firmware's own luac, so every string constant read as plaintext rather than a decompiler's guess. The native binaries — cab_meshd among them — were disassembled with a purpose-built listing tool plus objdump and strings. (No off-the-shelf decompiler was used for the native side.)
2. The parallel hunt with adversarial cross-review. The core loop was: launch several independent research agents in parallel, each chasing one candidate; run a synthesis pass to rank them; then a three-way adversarial verification in which each reviewer is instructed to refute the finding and re-derives it from scratch, disassembling the binary independently. A candidate was only trusted if all three reviewers reproduced it without disagreement. This caught at least one plausible-looking chain that did not survive scrutiny.
3. Two native leads, one winner. Two components surfaced as the strongest native targets and were chased side by side: the mesh daemon cab_meshd, and a previously-uncatalogued 304 KB deep-packet-inspection library (libsniper.so) reached from a root, always-on packet parser. The DPI library did contain a real memory-corruption bug — an ASN.1 decoder copying an unvalidated length into a fixed 1504-byte stack buffer with no canary — but its exploitability was blocked by ASLR with no information-leak primitive to defeat it. cab_meshd won the contest because its two chains need no memory corruption, no ASLR defeat, and no canary bypass at all. (The DPI-library bug remains a genuine, still-open finding rather than a dead end.)
4. Found → refuted → re-confirmed. The root-RCE chain had the most instructive arc. It was first found as a buffer overflow feeding a root system(). Live testing then refuted that reading: the one attacker-influenced field always receives a message-type byte whose zero terminates the string early, so a single chosen byte cannot both close the quoting and inject a command — it was downgraded to a bounded denial-of-service. A later pass re-confirmed a root RCE by an entirely different mechanism: the input filter is defeated downstream in shell, not in the C binary — an unquoted $@ word-splits the arguments and a base64 -d feeds an eval, so a blacklist-clean payload decodes into a command that runs as root. That final chain was reproduced live multiple times.
5. Hardware validation. A second RD03v2 unit was bought specifically for testing. A small script brought a factory unit into the initialised state (opening port 19553 via the web API, changing nothing else); the mesh HMAC was forged with the universal key; V1 leaked the admin verifier and minted a valid session; and V2's payload word-split through the real BusyBox shell to uid=0. All testing was performed on devices the author owns. No third-party or production systems were involved.
Disclosure timeline
| Date (UTC) | Event |
|---|---|
| 2026-08-14 | Day 0 — initial notification to security@xiaomi.com; 45-day timeline and publication date stated. Priority anchored with OpenTimestamps (Bitcoin-confirmed the next day). |
| 2026-08-17 | Day 3 — Xiaomi Security Center acknowledged; full technical package sent, encrypted to the MiSRC PGP key. |
| 2026-09-11 | Day 28 — no substantive technical response in the preceding 25 days; filed with CERT/CC via VINCE as VRF#26-09-SFWHW. |
| 2026-09-28 | Day 45 — publication of the advisory and the proof-of-concept, together. |
The PoC is released simultaneously and deliberately. The initial notification proposed withholding it for 30 days after a fix; that plan was changed on 2026-09-11 because no fix, fix plan, or timeline has been committed to, and because holding the exploit indefinitely would leave owners of unpatched — sometimes un-patchable — devices with nothing to act on.
Mitigations for owners
The product is unpatched. Because the attacker must already be on your network and needs no password, the question that decides your risk is: who else can reach this router's LAN or Wi-Fi?
This helps:
- Turn off guest Wi-Fi unless you fully trust the guests — the daemon is reachable from the guest network too. This is the single most effective containment step for a typical home.
- Know and prune who is on the network. Every client that can reach the router can become root on it.
- Do not deploy this router where untrusted clients share its layer-2 segment — shared housing, cafés, small-business guest access, conference networks.
- Move to OpenWrt where a port exists — it removes the vulnerable daemon entirely rather than merely containing it. Support is model-specific; check the OpenWrt device page for your exact hardware revision (the "AX3000T" name covers two different chips). For the analysed
RD03v2, the exploit chain doubles as an over-the-air OpenWrt installer, which is the reason the PoC ships at all. The same chain is also implemented for xmir-patcher (the community Xiaomi-router tool) as a fork; an upstream pull request is planned for the disclosure date, so the fork is the canonical home for now.
This does not help:
- Changing the admin password. V1 harvests the stored verifier regardless, and after exploitation the password is known to the attacker anyway.
- Disabling remote/WAN management or UPnP. The flaw is not WAN-facing.
- Hiding the SSID, MAC filtering, a longer Wi-Fi key. These raise the cost of joining the network; the attack needs no credentials once someone is on it.
- Waiting for a firmware update. None has been committed, and part of the affected range appears to have no update channel.
If you think you were compromised: a successful exploit gives root and can leave little trace. On a standalone router you never configured as a mesh node, a net-mode of whc_cap (the device's get_netmode API returning 4) is the closest tell. If in doubt, factory-reset, reflash from a trusted image, and rotate the admin password and Wi-Fi key — then treat everything that has passed through the router as disclosed.
Credit
Adriel Santos. Reported to Xiaomi and, via CERT/CC VINCE, VRF#26-09-SFWHW. CVSS 8.8 (V1) and 8.8 (V2). Full advisory, technical appendix, cross-model evidence and proof-of-concept: https://github.com/ADCDS/xiaomi-ax3000t-cabmeshd-disclosure.
Offline mirror. The complete package as a single archive: xiaomi-ax3000t-cabmeshd-disclosure.tar.gz (66 KB, git archive of the published tree). Verify integrity:
sha256 3abe3acc0e9ba9c7cddf69f81f4dbfcb78e2ff7c94d87134f4e3e033bc4d941a
Independent security research. Not affiliated with, endorsed by, or sponsored by Xiaomi or Redmi. Product and firmware names identify the affected devices only. All testing was performed on hardware the author owns; no third-party, production, or unauthorised systems were involved.