mardi 25 août 2015

UPnP IGD (Internet Gateway Device)

Présentation d'UPnP

UPnP (Plug and Play) est un standard accessible publiquement ici
Logo UPnP

UPnP est composé d'une suite de protocoles destinée à simplifier la configuration et l’interopérabilité des équipements pour l’utilisateur. UPnP est très présent dans les équipements grand public comme les Box Internet, NAS, Smart TV, Set-Top-Box et autres lecteur Blu-Ray connectés.

UPnP IGD

Les modems/routeurs (Box) implémentent plusieurs profils UPnP dont IGD (Internet Gateway Device). UPnP IGD offre des mécanismes de RPC (Remote Procedure Call) pour la configuration ou l’interrogation transparente des Box sans authentification.

Les fonctions couramment implantées dans les Box sont l’interrogation de l’adresse IP publique, quelques métriques d'usage, la redirection de ports entrants (pour les jeux vidéo, les applications multimédia et la téléphonie comme Skype). La fonction de gestion de la configuration des serveurs DNS n’est heureusement jamais implémentée. Si c'était le cas, il serait possible de modifier le serveur DNS de tous les équipements derrière la Box, exposant ceux-ci au phishing ou à la fraude au clic. 

Ainsi, UPnP IGD permet d'effectuer de la redirection de port (ou port mapping), sans authentification ou autorisation et de manière transparente pour l'usager. En clair, c'est un protocole intéressant pour les pirates pour faire de la NAT traversal depuis Internet.

Le fonctionnement d'UPnP

UPnP est composé d’une suite de protocoles en unicast et multicast, utilisant TCP et UDP pour véhiculer des messages HTTP avec des méthodes spécifiques. Le schéma ci-dessous illustre les cinématiques des différentes phases d'UPnP.

Le protocole UPnP
Les phases et protocoles UPnP

Découverte et annonces, le protocole SSDP

Le protocole de découverte de services, nommé SSDP (Simple Service Discovery), effectue des annonces périodiques NOTIFY ou des requêtes de découvertes M-SEARCH

Ces annonces et requêtes sont limitées au LAN et sont basées sur des échanges HTTPMU (HTTP sur UDP en multicast). Le groupe multicast utilisé est 239.255.255.250 et le port UDP est 1900. 

La réponse à une requête M-SEARCH est basée sur HTTPU (HTTP sur UDP en unicast).

Le header Location de l’entête HTTP SSDP contient l’URL décrivant le service distant au format XML. 


La description de services

La phase de description de service fait usage de requête GET HTTP classique pour informer sur les services implémentés par le ‘Device’ (serveur). La partie cliente est appelée ‘Control Point’ dans le jargon UPnP. 

Un tag « SCPDURL » dans un format XML décrit le path nécessaire pour l’invocation de procédure à distance. 


L'invocation de services 

L’appel de fonctions à distance est la phase « Control ». Elle est exécutée via une requête POST HTTP sur TCP au format SOAP XML. Un header spécifique SOAPaction doit être présent dans l'entête HTTP et définir la fonction distante appeléé (ex: AddPortMapping).

La notification

Une gestion de notification d’événements existe mais elle ne sera pas mis en oeuvre ici. Elle sert à enregistrer des Control-Points désirant recevoir certains types de notifications lors de la survenance d'événements.


Passons à la pratique d'UPnP

Nous allons regarder de plus près comment interagir avec UPnP.

Ecoute d'annonce SSDP et recherche de services

Une écoute passive du réseau dans le LAN privé permet de voir les annonces de services SSDP NOTIFY en action. En utilisant Wireshark avec un filtre UDP port 1900, on capture les messages SSDP :

$ sudo tshark -i eth0 udp port 1900
Running as user "root" and group "root". This could be dangerous.
Capturing on 'eth0'
  0.000000  192.168.0.1 -> 239.255.255.250 SSDP 342 NOTIFY * HTTP/1.1
  0.000819  192.168.0.1 -> 239.255.255.250 SSDP 398 NOTIFY * HTTP/1.1
  0.001247  192.168.0.1 -> 239.255.255.250 SSDP 326 NOTIFY * HTTP/1.1
  0.001729  192.168.0.1 -> 239.255.255.250 SSDP 318 NOTIFY * HTTP/1.1

L’émission d’une requête M-SEARCH en SSDP permet de connaître l’URL de description des services. Le programme miranda est utilisé à cette fin. 

miranda
upnp> msearch

Entering discovery mode for 'upnp:rootdevice', Ctl+C to stop...

****************************************************************
SSDP reply message from 192.168.0.1:80
XML file is located at http://192.168.0.1:80/RootDevice.xml
Device is running UPnP/1.0 UPnP/1.0 UPnP-Device-Host/1.0
****************************************************************

****************************************************************
SSDP reply message from 192.168.0.1:1900
XML file is located at http://192.168.0.1:1900/WFADevice.xml
Device is running POSIX UPnP/1.0 UPnP Stack/6.37.14.87
****************************************************************

^CDiscover mode halted...

Nous constatons que deux systèmes répondent à des requêtes M-SEARCH.

upnp> host list

       [0] 192.168.0.1:80
       [1] 192.168.0.1:1900

Une interrogation de la Box est ciblée pour obtenir l’URL de la description des services du profil UPnP IGD.

upnp> host get 0

Requesting device and service info for 192.168.0.1:80 (this could take a few seconds)...

Host data enumeration complete!

upnp> host info 0

xmlFile : http://192.168.0.1:80/RootDevice.xml
name : 192.168.0.1:80
proto : http://
serverType : None
upnpServer : UPnP/1.0 UPnP/1.0 UPnP-Device-Host/1.0
dataComplete : True
deviceList : {}


Nous cherchons les tags « SCPDURL » du fichier RootDevice.xml qui contiennent les paths des services implémentés.

curl http://192.168.0.1:80/RootDevice.xml | grep "SCPDURL"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2880  100  2880    0     0  29186      0 --:--:-- --:--:-- --:--:-- 29690
<SCPDURL>/Layer3Forwarding.xml</SCPDURL>
<SCPDURL>/WANCommonInterfaceConfig.xml</SCPDURL>
<SCPDURL>/WANIPConnection.xml</SCPDURL>

Nous possédons maintenant tous les éléments nécessaires pour monter une attaque contre cette implémentation UPnP IGD.


L'implémentation est elle robuste au NAT traversal ?

Bien que le standard UPnP ne soit pas précis concernant les règles applicables au Port Mapping (redirection de port), les bonnes pratiques exigent que seule une adresse du LAN interne puisse demander une redirection entrante et uniquement pour sa propre adresse. 

Remarque : Une requête demandant une redirection pour autrui devrait être refusée. En d’autres termes, seules les redirections vers le LAN privé sur l’interface interne (ici 192.168.0.0/24) doivent être autorisées. Aucune requête reçue sur l’interface externe, quelle que soit l’adresse source, ne doit être servie. Les redirections sont appliquées pour l’adresse du demandeur uniquement, par pour un tiers. Ces règles plus restrictives sont conformes à l’usage fait par les applications utilisant le PortMapping IGD (téléphonie, jeux, tunnel, etc.).


Tentative d'exploit depuis Internet

Les utilitaires UPnP disponibles publiquement ne permettent pas d’émettre uniquement la requête POST pour solliciter le service à distance. Ces programmes fonctionnent depuis le LAN privé car ils mettent en œuvre SSDP (i.e. multicast) préalablement pour découvrir tous les paramètres dynamiquement. Par respect des bonnes pratiques, ils n’effectuent pas (plus) de requêtes de redirection pour une adresse tierce.

Un code d’exploitation en python a été développé (voir en fin d'article) pour effectuer des redirections dérogeant aux règles des bonnes pratiques. Ce code n’exécute que la requête POST de la phase « Control » en SOAP XML avec les paramètres adéquats.

Une série de tests est effectuée pour des requêtes émises depuis l’interface interne pour des redirections d’autres adresses. La machine RPi joue le rôle de la victime dans le LAN (192.168.0.13). La machine Kali joue le rôle de l'attaquant est émet une requête UPnP depuis Internet.

Kali demande une redirection du port TCP 22 pour l'adresse de RPi en adressant la requête POST à l'adresse publique xx.xx.xx.xx:8080.

pascal@Kali:~$ upnp-sploit.py 
[*] POST to http://XX.XX.XX.XX:8080/WANIPConnection
[+] Success: adding TCP port from :22 -> 192.168.0.13:22

En listant les redirections de ports avec le client UPnP upnpc (de miniupnp) depuis le LAN privé, nous constatons que a règle de redirection est bien configurée :

pascal@Kali:~$ upnpc -l
upnpc : miniupnpc library test client. (c) 2006-2010 Thomas Bernard
Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
for more information.
List of UPNP devices found on the network :
 desc: http://192.168.0.1:80/RootDevice.xml
 st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

Found valid IGD : http://192.168.0.1:80/WANIPConnection
Local LAN ip address : 192.168.0.11
Connection Type : IP_Routed
Status : Connected, uptime=506520s, LastConnectionError : ERROR_NONE
  Time started : Fri Apr 10 15:42:08 2015
MaxBitRateDown : 100000000 bps   MaxBitRateUp 100000000 bps
ExternalIPAddress = XX.XX.XX.XX
 0 TCP    22->192.168.0.13:22    'Hack the rpi' ''
GetGenericPortMappingEntry() returned 713 (SpecifiedArrayIndexInvalid)

Dans la réponse, l'adresse publique a été anonymisée. upnpc effectue des requêtes pour tous les services à distance implémentés (connection type, status, uptime, last connection error, métrique d'usage, adresse IP externe et listage des port mapping).

Une tentative de connexion en SSH sur l’interface publique XX.XX.XX.XX de la Box redirige effectivement le flux vers le système RPi dans le LAN privé conformément à la règle de redirection. 

$ ssh pi@xx.xx.xx.xx
pi@xx.xx.xx.xx's password:
Linux rpi 3.18.10+ #774 PREEMPT Wed Mar 25 13:58:34 GMT 2015 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Apr 16 09:27:41 2015 from xx-xx-xx-xx.rev.domain.fr
pi@rpi ~ $ ifconfig |grep 192.168
          inet adr:192.168.0.13  Bcast:192.168.0.255  Masque:255.255.255.0

La redirection a bien été appliquée et exécutée ! La connexion en SSH vers l'IP publique de la Box a bien été redirigée vers la machine RPi dans le LAN privé. 

L’acceptation de commandes de redirection pour une adresse tierce est critique et doit être absolument proscrite car UPnP IGD ne requiert aucune authentification. Dans la même veine, l'acceptation d'une requête venant de l'interface publique doit aussi être refusée. De telles commandes permettent de traverser les règles de firewall et exposent ainsi les systèmes privés depuis Internet.

Redirection de l'interface de management Web et proxy ouvert 

Une interface Web de management est disponible uniquement depuis le LAN interne de la Box sur le port 80. Une tentative de redirection vers d'un port externe, par exemple 8000, vers le port interne 80 n'a pas fonctionné sur ce modèle de Box.  Si cela avait été le cas, alors l'interface de management aurait été accessible depuis Internet avec l'authentification par défaut (bien connu pour cette Box). 

Dans le même esprit, une tentative de redirection d'une adresse publique vers une autre adresse publique n'a pas fonctionné. Cela aurait fourni un proxy ouvert vers un site publique spécifique permettant de masquer l'adresse d'origine du pirate lors d'une attaque. C'est l'adresse du propriétaire de la Box agissant en proxy qui serait vue par la victime de l'attaque. 

Conclusion

La qualité des implémentations UPnP IGD des modems routeurs est très variable. Certaines ne sont pas vulnérables quand d'autres sont ouvertes directement depuis Internet. 

UPnP est peu connu ou maîtrisé par les pentesteurs. C'est regrettable car le monde de l'entreprise est concerné. Par exemple, les imprimantes utilisent aussi UPnP. De surcroît, de nouveau profil voit le jour comme c'est le cas pour la domotique, ouvrant ainsi la voie à de nouveaux vecteurs d'attaque.  


Code de l'exploit

code exploit UPnp IGD
Code python upnp_sploit.py



lundi 24 août 2015

Recherche de port série

Inspection visuelle du PCB

L’objet de ce nouvel article est de rechercher un accès au port série sur le PCB (Printed Circuit Board) d’un système embarqué comme un modem routeur.
Inspection visuelle du PCB
PCB d'un système embarqué
L’examen du PCB fait apparaître deux blocs de quatre contacts ressemblant fortement à des points d’accès au port série. Dans l'image ci-dessous, il s'agit de vias qui comportent des points de soudure.
Points de contact de port série ?
Contacts candidats au port série
Mais cela pourrait être de simple vias vides ou pin holes dans lesquels il faudrait souder des headers  (broches) ou utiliser des grip-fils pour connecter les points de contact.
via et broche à souder
Vias et headers à souder
Un via est un trou en métal dans le PCB qui est connecté à des pistes pour établir des liaisons électriques dans les couches de silicium.
via électronique, interconnexion sur la carte
Vias et connectique dans les couches de silicium

Le port série, console ou UART

Un port série possède traditionnellement quatre contacts :
  • GND (masse), 
  • Vcc (alimentation), 
  • Tx (transmission) 
  • Rx (réception). 
Les industriels ont besoin de disposer de ports série pour le reconditionnement ou le débogage de terminaux. Parfois, ces ports sont cachés dans d’autres interfaces physiques (prise jack, péritel, ..) ou disséminés sur le PCB. Le groupement de points de contact par quatre ainsi que la proximité du SoC (System on Chip) font de ces vias des candidats sérieux pour des ports série. Un suivi des traces (lignes métalliques) sur le PCB sur les deux faces du PCB peut confirmer cette supposition à moins que les lignes soient enfouies dans les couches de silicium. Dans ce cas, il faudrait pouvoir faire une radiographie aux rayons X.

L’intérêt d’un port série est d’offrir un port de debug pour accéder au chargeur de démarrage (bootloader), observer les messages du démarrage (bootloader, noyau de l'OS, application) et interagir avec le terminal via un shell ou un menu interactif en ligne de commande. Le port série offre aussi la possibilité d’extraire ou copier la mémoire ou de flasher des images en mémoire non volatile. Le port série est ainsi une cible de choix pour un attaquant.

La méthode de recherche du port série

La recherche du port série, habituellement appelé UART (Universal Asynchronous Receiver Transmitter), est réalisée avec un multimètre numérique.
Multimètre numérique sonore avec fonction hold
Multimètre numérique
La méthode de recherche consiste à procéder par élimination pour identifier le rôles des différents points de contacts possibles, puis leurs caractéristiques.
  1. L’inspection visuelle préalable permet d'identifier des contacts ou vias candidats sur le PCB.
  2. Lorsque des points de contact sont identifiés, il faut rechercher en priorité la masse (GND). Un test de continuité entre la masse sur le PCB (par exemple un shield ou une pièce métallique importante) et chaque point de contact permet de trouver celui qui est directement relié à la masse grâce au bip sonore continue émis par le multimètre.
  3. L'étape suivante consiste à identifier la broche Tx car celle-ci est facile à identifier lorsque des données sont émises. Pour cela, la séquence de démarrage est appropriée car elle génère un flux continu de données sur le port console. Une mesure de l’intensité avec le multimètre permet de détecter des fluctuations du voltage lors du boot, oscillant entre 0 et 3,6 Volts dans notre cas. Cette fluctuation est provoquée par la transmission des données.
  4. Il ne reste plus qu’à identifier Vcc et Rx. Lorsque les paramètres de la connexion UART sont identifiés grâce à Tx, (cf. pragraphe suivant) il suffit d’émettre des caractères vers l’un de ces contacts et vérifier l’écho en retour pour identifier la broche Rx.

L'adaptateur USB série

Pour se connecter au port série du PCB, un adaptateur USB série (FTDI 232) est nécessaire. Un modèle comme celui ci-dessous supporte 3,3V ou 5V et coûte quelques euros.
Adaptateur USB série FTDI
Adaptateur USB série
L'adaptateur série USB se connecte en USB sur l’ordinateur du pentesteur et sur les contacts GND, Tx et Rx du PCB.

Schéma de raccordement série
Schéma de raccordement d'un adaptateur USB série
Strap flexible grip-fil (pince)
Pince grip-fil
Les broches transmission et réception doivent être croisées entre l’adaptateur USB série et les ports sur le PCB du système analysé. Classiquement, les points de contact sont soit des vias destinés à recevoir des broches, soit des headers (broches) déjà présents. Dans le cas étudié, des points de soudure sur des vias étaient présents, mais l'accès au verso de la carte était inexploitable. Il a fallu utiliser des câbles grip-fil (strap flexible muni de pince) pour connecter l'adaptateur série.
Accès port série en action avec grip-fil sur soudure
Accès au port série avec câbles grip-fil

Le programme pilotant la liaison série

L’utilitaire utilisé sur le PC sous Linux de l'auditeur pour établir la connexion avec l’adaptateur USB série est minicom, qui utilise le pseudo périphérique /dev/ttyUSB0 pour communiquer.

$ sudo minicom –o –D /dev/ttyUSB0
Bienvenue avec minicom 2.6.1

OPTIONS: I18n
Compilé le Feb 11 2012, 18:12:55.
Port /dev/ttyUSB0

Tapez CTRL-A Z pour voir l'aide concernant les touches spéciales



Après quelques tentatives de connexion pour déterminer les caractéristiques de la communication, le port console de la carte s’avère utiliser une vitesse de transmission à 115 200 bauds, 8-bits de données, aucune parité et un bit de stop (en abrégé 115200 8N1). Le contrôle de flux matériel doit être désactivé.

L’étape suivante consiste à démarrer le modem routeur lorsque la connexion au port série via minicom est établie. Les séquences de démarrage suivantes s'affichent :
BCM3384A8 0002A080 memsys2g800x16 2p5bld1

SHMOO VER 1.17
MCB

PKID 20131007  050B6000  050B0000  04B4103E  00001C00 

S300001B7 
000011A0 
+00000004  >0000011A 
t00000020  0000003C 
@000000B4  ^0000001B 

RDEN W0 00000020  00000006  00000000 


RDLY W0 00000003 

RDQS W0
[...]
Sync: 0
MemSize:            256 M
Chip ID:     BCM3384Z-B0

BootLoader Version: 2.5.0beta1 Rev01 Release spiboot dual-flash memsys2g800x16 avs linux
Build Date: Sep  9 2014
Build Time: 19:36:18
SPI flash ID 0x010219, size 32MB, block size 64KB, write buffer 256, flags 0x2
Cust key size 128

Signature/PID: d06f


Image 1 Program Header:
   Signature: d06f
     Control: 0005
   Major Rev: 0003
   Minor Rev: 0000
  Build Time: 2015/1/13 08:19:06 Z
 File Length: 5024538 bytes
Load Address: 80004000
    Filename: EMTA62-1_NCC_1.2.3-20150113.bin
         HCS: c6fd
         CRC: 51a22add

Found image 1 at offset 30000

Enter '1', '2', or 'p' within 2 seconds or take default...

Conclusion

Voilà un accès au port série d'un modem routeur réussi. La suite est confidentielle car elle mettrait en péril le produit audité et ne respecterait pas la déontologie du ethical hacking. Sachez néanmoins qu’il a été possible de consulter le mapping de la mémoire non volatile, permettant ainsi de flasher les partitions contenant le firmware (bootloader, kernel et application) et d'extraire la clef indivuduelle du périphérique.

dimanche 23 août 2015

Dump de mémoire flash SPI avec Rasbperry Pi

Le protocole SPI

Le protocole SPI (Serial Peripheral Interface) est un protocole série synchrone largement utilisé dans les systèmes embarqués par les SoC (System on Chip) pour communiquer avec les composants de mémoire non-volatile externes. Ces architectures sont courantes dans les systèmes embarqués des Box Internet (modem router), Set-Top-Box, Smart TV, Media center, NAS, Femtocells ou encore les Box domotiques. Le protocole SPI est un protocole série synchrone qui suit un modèle Maître/Esclave.

Le protocole SPI offre ainsi une communication entre un maître et un ou plusieurs esclaves. Le maître impose la fréquence d’horloge pour synchroniser les échanges et il sélectionne l’esclave avec lequel il souhaite communiquer. Les données sont mises sur la ligne de bus adéquate MISO ou MOSI. La ligne MOSI (Master Out Slave In) permet d’envoyer des données depuis le maître vers l’esclave. La ligne MISO (Master In Slave Out) est en haute-impédance jusqu’au moment où l’esclave est sélectionné et où il doit envoyer ses données.
Schéma protocole Serial Peripheral Interface (SPI)
Serial Peripheral Interface
Lorsque l’on dispose de plusieurs esclaves, ils peuvent être connectés ensemble sur le bus en daisy-chain. Le maître sélectionne l'esclave avec lequel il souhaite communiquer parmi ses multiples sorties Slave Select (SS0, SS1, etc.). Le signal d'horloge (SCLK) est généré par le maître, ce signal sert à cadencer les échanges. Enfin, la broche de la masse ou ground en anglais (GND) est raccordé à une masse commune entre les composants.

Dans le monde de l'embarqué, un reverser ou pentesteur cherchera à dumper la mémoire flash contenant le firmware (bootloader, OS et applications) pour le reverser et aussi extraire les données intéressantes (configuration et autres données sensibles telles que des clefs cryptographiques et mot de passe). 

Il faut donc disposer d'un micro-contrôleur disposant d'un maître SPI que l'on peut configurer et programmer. Le moyen économique pour piloter un échange SPI est d'utiliser un "Bus pirate" de Dangerous Prototype ou une carte Raspberry Pi (RPi). L'article détaille une mise en oeuvre à base de RPi. La Raspberry Pi est construite à partir d'un SoC Broadcom ARM, elle est largement répandue et bénéficie une grande communauté active sur Internet.
Carte Raspberry Pi (RPi)
Carte Raspberry Pi

Déterminer la version matérielle de la RPi

Le postulat est que vous disposiez déjà d'une carte RPi avec la distribution Rapsbian dérivée de Debian.

Les informations du CPU, contenues dans le pseudo file system /proc, donne la version matérielle avec la commande :
pi@rpi ~/spi $ cat /proc/cpuinfo
processor    : 0
model name   : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS     : 2.00
Features     : half thumb fastmult vfp edsp java tls
CPU implementer: 0x41
CPU architecture: 7
CPU variant  : 0x0
CPU part     : 0xb76
CPU revision : 7
Hardware     : BCM2708
Revision     : 000e
Serial       : 000000000b1f65aa

Le champ Revision donne le code de révision du matériel de votre RPi. Le tableau ci-dessous permet d'identifier le modèle de votre carte. Dans notre cas il s'agit du Model B Revision 2.0.

Tableau des versions matérielles de carte Raspberrry Pi (RPi)

La première étape est de réaliser une mise à jour de la distribution Raspbian.
pi@rpi ~ $ sudo apt-get update
pi@rpi ~ $ sudo apt-get upgrade

Dans le fichier de blacklist des modules noyau, décommentez le module SPI spi-bcm2708 afin qu'il soit chargé, puis redémarrez la carte.
pi@rpi ~ $ cat /etc/modprobe.d/raspi-blacklist.conf
# blacklist spi and i2c by default (many users don't need them)
# blacklist spi-bcm2708
blacklist i2c-bcm2708
pi@rpi ~ $ reboot

Après le reboot, il faut charger le module si ce n'est pas déjà fait (vérifier avec la commande lsmod).
pi@rpi ~ $ sudo modprobe spi-bcm2708
pi@rpi ~ $ lsmod |grep spi
spi_bcm2708             6018  0 

Si une erreur apparaît, il faut alors mettre à jour le firmware de la carte RPi pour supporter le protocole SPI sur les GPIO. Le firmware est indépendant du système d'exploitation Raspbian et dépend du SoC.
pi@rpi ~ $ sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update  
pi@rpi ~ $ sudo chmod +x /usr/bin/rpi-update
pi@rpi ~ $ sudo rpi-update
*** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
*** Performing self-update
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  8107  100  8107    0     0  23898      0 --:--:-- --:--:-- --:--:-- 30708
 *** Relaunching after update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
 *** We're running for the first time
 *** Backing up files (this will take a few minutes)
 *** Backing up firmware
 *** Backing up modules 3.18.7+
 *** Downloading specific firmware revision (this will take a few minutes)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   168    0   168    0     0    334      0 --:--:-- --:--:-- --:--:--   443
100 44.5M  100 44.5M    0     0   714k      0  0:01:03  0:01:03 --:--:--  902k
 *** Updating firmware
 *** Updating kernel modules
 *** depmod 3.18.10-v7+
 *** depmod 3.18.10+
 *** Updating VideoCore libraries
 *** Using HardFP libraries
 *** Updating SDK
 *** Running ldconfig
 *** Storing current firmware revision
 *** Deleting downloaded files
 *** Syncing changes to disk
 *** If no errors appeared, your firmware was successfully updated to 8751db9fd7138848c29cc55ec05f95c9eea80acb
 *** A reboot is needed to activate the new firmware

Ensuite, il faut modifier la configuration dnas le fichier /boot/config.txt de la carte RPi et ajouter en fin de fichier la directive dtparam=spi=on puis redémarrer.
pi@rpi ~ $ sudo su -
root@rpi:~# echo dtparam=spi=on >> /boot/config.txt
pi@rpi ~ $ sudo reboot

Après redémarrage, il faut charger le module noyau puis vérifier que les pseudo périphériques spidev ont été créés par le module.
pi@rpi ~ $ ls -l /dev/spi*
crw-rw---T 1 root spi 153, 0 janv.  1  1970 /dev/spidev0.0
crw-rw---T 1 root spi 153, 1 janv.  1  1970 /dev/spidev0.1

Vérifier le support du protocole SPI

Pour vérifier le support du protocole SPI sur les GPIO de la carte RPi, il est nécesaire de créer une boucle sur la RPi en connectant la broche MOSI (GPIO 10) à la broche MISO (GPIO9), puis d'exécuter la commande de test spidev_test. Le code source de cette commande est .

Attention, il faut utiliser l'ancien code, sinon il faut substituer "*device = "/dev/spidev1.1"  par "/dev/spidev0.0" :
pi@rpi ~/spi $ gcc spidev_test.c -o spidev_test
pi@rpi ~/spi $ sudo ./spidev_test
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D

Le mapping des broches GPIO pour une carte RPi de Revision 2 est illustré ci-dessous.
Mapping des GPIO de la carte RAspberry Pi (RPi)
Mapping GPIO RPi B rev 2

Dumper une mémoire flash

Afin de vider le contenu d'une mémoire flash série, il est nécessaire que le packaging du composant possède des broches apparentes (ex: SOIC). Un composant BGA (Ball Grid Array) ne sera pas dumpable avec des moyens artisanaux.
Contact Ball Grid Array (BGA)
Ball Grid Array

Broches apparentes SOIC d'une puce mémoire
Broches apparentes SOIC
Pour connecter une mémoire flash série supportant le protocole SPI, il faut récupérer la datasheet auprès du fabricant pour connaître le brochage de la puce mémoire. Ensuite, deux options se présentent. La première est de déssouder la mémoire flash pour la dumper, l'autre est de positionner une sonde in-situ :
  1. Le déssoudage doit éviter d'endommager la mémoire flash. Cette méthode est invasive car le PCB sera détérioré et inutilisable à moins d'y souder un socket pour remettre en place la mémoire. Attention à la température lors du dessoudage, si celle-ci est trop élevée les pistes métalliques sur le PCB peuvent se dissocier de la carte et rompre la connectivité ! Pour travailler correctement, il faut disposer d'une station de soudage de précision, de panne de qualité et de loupe adaptée. 
  2. La sonde est plus facile à mettre en oeuvre, mais des problèmes de tension peuvent survenir sur la carte empêchant toute capture correcte d'un signal. En effet, en laissant la mémoire flash en place, le courant alimente les composants environnants qui peuvent interférer. Dans ce cas, la seule option est de déssouder le composant.

Une sonde de test à pince (clip) de 16 voies coûte environ 10 $.
Sonde de test à pince (clip probe)
Sonde clip 3M 16 voies
Le cas présenté dans cet article cible le vidage mémoire d'une mémoire flash Spansion SPI à 16 broches. Ce composant est soudé sur le PCB d'un système embarqué multimédia grand public (le modèle n'est pas révélé pour des raisons éthiques). Une photo de la puce mémoire montre la sérigraphie permettant d'identifier le modèle de composant chez le fabricant.


Composant mémoire flash Spansion
Sérigraphie de la mémoire flash Spansion
Voici à quoi ressemble la sonde in-situ connectée à la mémoire flash sur le PCB.


Sonde connecté à la puce mémoire sur le PCB
Sonde connectée sur la mémoire flash sur le PCB
Côté RPi, les GPIO sont reliés aux broches de la sonde avec des straps flexibles.
Les GPIO de la RPI connecté pour le protocole SPI
Broches GPIO sur la RPi
Un analyseur logique Logic Pro Saleae a été utilisé préalablement pour vérifier l'identification des broches de la mémoire flash.


Capture d'échange SPI avec analyseur logique Saleae
Capture d'échange SPI sur la mémoire avec un analyseur logique
Le schéma de connexion est illustré ci-dessous, les broches CE (Chip Enable) correspondent aux broches SS (Slave Select):
Schéma de raccordements RPi et mémoire flash SPI
Schéma de connexion

Flashrom

Flashrom est un logiciel Open Source sous licence GPLv2. Cet utilitaire universel sert à programmer des mémoires Flash (lecture, écriture, détection, effacement) en packaging DIP, PLCC, SOIC, TSOP ou BGA. 

Flashrom supporte les interfaces LPC, FWH et SPI. Il supporte plus de 450 familles de composants de mémoires Flash, 286 chipsets et 450 cartes mères. Malheureusement il n'est pas disponible sur le repository de Raspbian. Il faut donc le télécharger et le compiler sur la carte RPi. Plus d'information ici.


pi@rpi ~ $ mkdir flashrom; cd flashrom/
pi@rpi ~/flashrom $ git clone https://github.com/stefanct/flashrom
pi@rpi ~/flashrom $ sudo apt-get install libpci-dev  pciutils libftdi-dev zlib1g-dev
pi@rpi ~/flashrom $ make
pi@rpi ~/flashrom $ sudo make install
Replacing all version templates with 0.9.8-r1887.
Checking for a C compiler... found.
Target arch is arm
Target OS is Linux
Checking for FTDI support... found.
Checking for FT232H support in libftdi... found.
Checking if Linux SPI headers are present... yes.
Checking for utsname support... found.
mkdir -p /usr/local/sbin
mkdir -p /usr/local/share/man/man8
install -m 0755 flashrom /usr/local/sbin
install -m 0644 flashrom.8 /usr/local/share/man/man8

Flashrom ne supporte pour l'instant que des mémoires jusqu'à 16 Mo en adressage sur 24-bit .Pour des mémoires de plus grande capacité, il faut supporter un adressage 32-bits qui est actuellement non supporté par flashrom. Le passage en mode d'adressage étendu est réalisé en activant un bit dans un registre de configuration puis en utilisant soit des commandes standards, soit des commandes spécifiques, avec des situations variables selon les fabricants.

Flashrom permet de lister les puces mémoire supportées, les modèles de mémoire Spansion supportées sont listées ci-dessous :
pi@rpi ~ $ flashrom -L | grep -i spansion                         
Spansion      S25FL004A                              512  SPI     
Spansion      S25FL008A              PRE            1024  SPI     
Spansion      S25FL016A              PR             2048  SPI     
Spansion      S25FL032A/P            PREW           4096  SPI     
Spansion      S25FL064A/P            PREW           8192  SPI     
Spansion      S25FL204K                              512  SPI     
Spansion      S25FL208K                             1024  SPI     
Spansion      S25FL116K/                            2048  SPI     
Spansion      S25FL132K                             4096  SPI     
Spansion      S25FL164K              PREW           8192  SPI     
Spansion      S25FL127S-64kB         PREW          16384  SPI     
Spansion      S25FL127S-256kB                      16384  SPI     
Spansion      S25FL128P......0                     16384  SPI     
Spansion      S25FL128P......1                     16384  SPI     
Spansion      S25FL128S......0                     16384  SPI     
Spansion      S25FL128S......1                     16384  SPI     
Spansion      S25FL129P......0       PREW          16384  SPI     
Spansion      S25FL129P......1                     16384  SPI      

La datasheet du fabricant permet d'identifier le modèle de composant. Lorsque celui-ci ou un modèle approchant est supporté par flashrom, il suffit de lire la mémoire et de copier le contenu dans un fichier.

Pour réaliser cette étape, nous utilisons l’interface noyau /etc/spidev0.0 (bus 0 et Chip Select 0) pour le type de programmateur linux_spi. La commande ci-dessous effectue une lecture (-r pour read) et écrit le contenu dans le fichier flash128.rom. Elle force (-f) l'usage du profil de chip (-c)  ' S25FL128S......0' :
pi@rpi ~/spi $ flashrom -p linux_spi:dev=/dev/spidev0.0 -r flash128.rom -f -c 'S25FL128S......0'
flashrom v0.9.8-r1887 on Linux 3.18.10+ (armv6l)
flashrom is free software, get the source code at http://www.flashrom.org

Calibrating delay loop... OK.
No EEPROM/flash device found.
Force read (-f -r -c) requested, pretending the chip is there:
Assuming Spansion flash chip "S25FL128S......0" (16384 kB, SPI) on linux_spi.
Please note that forced reads most likely contain garbage.

Reading flash... done.

La taille du fichier flash128.rom est de 16 Mo, il contient le contenu de la flash.


pi@rpi ~/spi $ ls -l flash128.rom

-rw-r--r-- 1 pi pi 16777216 avril  8 12:44 flash128.rom



Conclusion

L'analyse du contenu du dump d'une mémoire flash fera l'objet d'un prochain article traitant du reverse de firmware et de la recherche de clefs cryptographiques. Cependant, jetez un œil sur la recherche de port série ici.