From bb8723546de777307df2d58f2e56166b99893110 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Wed, 6 May 2026 19:50:55 +0000 Subject: [PATCH] Add content from: Make it Blink: Over-the-Air Exploitation of the Philips Hue ... --- .../firmware-analysis/README.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/hardware-physical-access/firmware-analysis/README.md b/src/hardware-physical-access/firmware-analysis/README.md index 53e6a858542..6e973f2b43e 100644 --- a/src/hardware-physical-access/firmware-analysis/README.md +++ b/src/hardware-physical-access/firmware-analysis/README.md @@ -337,6 +337,64 @@ gdb-multiarch /path/to/targetd target remote :1234 ``` +### Zigbee / radio-co-processor message mapping + +On IoT hubs the RF stack is often split between a **radio MCU** and a Linux userland process. A useful workflow is to map the path: + +1. **RF frame** on the air +2. **controller-side parser** on the radio MCU +3. **serial/UART text or TLV protocol** forwarded to Linux (for example `/dev/tty*`) +4. **application dispatcher** in the main daemon +5. **protocol-specific handler / state machine** + +This architecture creates two reversing targets instead of one. If the controller converts binary radio frames into a textual protocol such as `Group,Command,arg1,arg2,...`, recover: + +- The **message groups** and dispatch tables +- Which messages can come from the **network** versus the controller itself +- The exact **manufacturer-specific discriminator fields** (for example Zigbee `manufacturer_code` and custom `cluster_command`) +- Which handlers are only reachable during **commissioning**, discovery, or firmware/model download phases + +For Zigbee specifically, capture pairing traffic and check whether the target still relies on the default **Link Key** `ZigBeeAlliance09`. If so, sniffing commissioning traffic may expose the **Network Key**. Zigbee 3.0 install codes reduce this exposure, so note whether the tested device actually enforces them. + +### Manufacturer-specific protocol handlers and FSM-gated reachability + +Vendor-specific Zigbee/ZCL commands are often a better target than standardized clusters because they feed **custom parsing code** and internal **FSMs** with less battle-tested validation. + +Practical workflow: + +- Reverse the command dispatcher until you find the **vendor-only handler**. +- Recover the **FSM state**, **event**, **check**, **action**, and **next-state** tables. +- Identify **transitional states** that auto-advance and retry/error branches that eventually reset or free attacker-controlled state. +- Confirm which legitimate protocol exchanges are required to place the daemon in the vulnerable state instead of assuming the buggy handler is always reachable. + +For timing-sensitive protocols, packet replay from a Python framework may be too slow. A more reliable approach is to emulate a legitimate device on real hardware (for example an **nRF52840**) with a vendor-grade stack so you can expose the correct **endpoints**, **attributes**, and commissioning timing. + +### Fragmented-download bug class in embedded daemons + +A recurring firmware bug class appears in **fragmented blob/model/configuration downloads**: + +1. The **first fragment** (`offset == 0`) stores `ctx->total_size` and allocates `malloc(total_size)`. +2. Later fragments only validate the attacker-controlled **packet-local** fields such as `packet_total_size >= offset + chunk_len`. +3. The copy uses `memcpy(&ctx->buffer[offset], chunk, chunk_len)` without checking against the **original allocated size**. + +This lets an attacker send: + +- A first valid fragment with a **small** declared total size to force a small heap allocation. +- A later fragment with the **expected offset** but a larger `chunk_len`. +- A forged packet-local size that satisfies the fresh checks while still overflowing the originally allocated buffer. + +When the vulnerable path sits behind commissioning logic, exploitation must include enough **device emulation** to drive the target into the expected model-download or blob-download state before sending the malformed fragments. + +### Protocol-driven `free()` triggers + +In embedded daemons, the easiest way to trigger heap metadata exploitation is often not "wait for cleanup" but **force the protocol's own error handling**: + +- Send malformed follow-up fragments to push the FSM into **retry** or **error** states. +- Exceed the retry threshold so the daemon **resets context** and frees the corrupted buffer. +- Use this predictable `free()` to trigger allocator-side primitives before the process crashes for unrelated reasons. + +This is especially useful against **musl/uClibc/dlmalloc-like** allocators in embedded Linux, where corrupting chunk metadata can turn unlink/unbin logic into a write primitive. A stable pattern is to corrupt a **size field** to redirect allocator traversal into **fake chunks staged inside the overflowed buffer**, instead of immediately clobbering real bin pointers and crashing the process. + ## Binary Exploitation and Proof-of-Concept Developing a PoC for identified vulnerabilities requires a deep understanding of the target architecture and programming in lower-level languages. Binary runtime protections in embedded systems are rare, but when present, techniques like Return Oriented Programming (ROP) may be necessary. @@ -432,5 +490,6 @@ To practice discovering vulnerabilities in firmware, use the following vulnerabl - [Exploiting zero days in abandoned hardware – Trail of Bits blog](https://blog.trailofbits.com/2025/07/25/exploiting-zero-days-in-abandoned-hardware/) - [How a $20 Smart Device Gave Me Access to Your Home](https://bishopfox.com/blog/how-a-20-smart-device-gave-me-access-to-your-home) - [Now You See mi: Now You're Pwned](https://labs.taszk.io/articles/post/nowyouseemi/) +- [Make it Blink: Over-the-Air Exploitation of the Philips Hue Bridge](https://www.synacktiv.com/en/publications/make-it-blink-over-the-air-exploitation-of-the-philips-hue-bridge.html) {{#include ../../banners/hacktricks-training.md}}