SSTIC 2015 - Jour 1
Bon, c’est repartis pour un nouveau SSTIC.
Cette année, les actes sont très réussis, et Très épais… ça pèse lourd dans le sac. Le ton est donné, cette année il y aura du lourd 😉
Sécurité et ingénierie dans chromium – Julien Tinnes
En 2005 on essayait de chopper des 0-dayz à l’aide de honeypots, on essayait de comprendre les vulnérabilités et le grand public était à la masse. Les vulnérabilités des navigateurs webs n’étaient pas très connues, là ou désormais elles ont toutes leur logo, un nom amusant et font le buzz. En 2005, la sécurité était réactive, produisait des patchs et zou. Maintenant, l’ingénierie de la sécurité rejoint l’ingénierie logicielle sur certains domaines, et parfois s’y oppose.
Dans les années 90, on rêvait de pouvoir télécharger et exécuter des applications de façon sécurisés, et de pouvoir les isoler les unes des autres. En quelque sortes, le Web à réalisé ce rêve… Les applications web sont des applications HTML5+JavaScript téléchargés et exécutés par le navigateur, qui est en charge de la sécurité et du cloisonnement des applications.
En 2008, le navigateur n’était qu’un gros processus, avec plein de tab, chacune possédant un lot de threads qui s’exécutent dans ce processus. Du coup lorsque ça crash, bah tout le navigateur se gaufre. Le design de chromium à eu pour but d’isoler les fautes, du coup l’exécution des tab dans des process séparés permet de faire de l’isolation de faute, mais il faut utiliser des IPC pour que les tab communiquent avec l’interface utilisateur. Ces IPC ont le mérite d’exhiber les dépendances systèmes et inter-process.C’est au travers du contrôle de ces IPC et des syscall que l’ingénierie de chromium permet la séparation et la restriction des privilèges de chaque applications au travers de sandboxes.
Si un process peut déboguer un autre process, il peut « voler » ou utiliser ses privilèges (injection de thread, etc…). De même si P1 peut manipuler les fichiers de P2, par transitivité P1 contrôle P2 et ses privilèges. Sous Linux, les « PID namespaces » on permit (dans les premières versions de chromium) de mettre en place une hiérarchie entre les processus, en plus de l’isolation. Restait à régler les problème d’accès fichier. Reste l’isolation du processus vis à vis du noyau, pour éviter toute escalade de privilèges via l’exploitation de vulnérabilités kernel. Pour obtenir cette isolation, l’équipe chromium à d’abord utilisé seccomp BPF.Mais c’est très complexe, et on peut rapidement faire des erreurs, et oublier de filtrer des paramètres permettant de contourner ce filtrage, d’ou la mise en oeuvre d’un DSL.
Sous windows, c’était compliqué d’effectuer un tel filtrage des syscall noyau, mais depuis windows8, une api permett d’effectuer ce filtrage. L’effet de bord intéressant, lorsqu’on restreint les syscall, on réduit aussi les possibilités de bugs et donc on améliore la stabilité du logiciel.
Gérer la SOP au niveau des communications interprocess et des sandboxes peut vraiment rendre le sandboxing et l’isolation complexe. Du coup pour maintenir l’isolation, tout en respectant la SOP, il faut créer des processus par iframe, et c’est un problème en cours de résolution.
Si on arrive à créer une sandbox parfaite, on pourrais envisager de laisser du code natif s’exécuter 😉 mais soyons sérieux, la défense en profondeur à du bon.
C’est pas le tout d’avoir une solution, il faut aussi la tester. Pour ce faire, le projet ClusterFuzz à vu le jour, pour mettre à l’épreuve la sécurité de Chromium. Ces campagnes de fuzzing ont découvert pas mal de bugs, et la correction de ces bugs est de la responsabilité de tous les acteurs du developpement de chromium. ClusterFuzz est tellement bien intégré, que les cas de tests générant des bugs deviennent des tests de non-régression une fois que le bug est résolut. L’intégration continue à l’extrème 🙂
La production de mises à jour dans un délais très court est très complexe, mais c’est un enjeux majeur pour lutter contre les vulnérabilités du navigateur. Le Bug Bounty permet aussi de venir challenger l’équipe de dev et de sécurité de Chromium.
Avec tout ça, on s’approche du rêve des années 90, les applications peuvent etre isolées entre elles, mais reste à les télécharger de façon sécurisé. Et là encore, c’est la galère, au vu des vulnérabilités SSL et des problèmes de gestion des certificats pourris produits par des autorités de certification peu regardantes.
Il y a aussi le problème du système d’exploitation, avec ses malwares et cie… Bon on a essayé avec le TPM, mais le système continue de booter, même si il y a un problème (evil maid attack). Du coup pour ChromeOS, l’idée c’est d’enchainer les vérifications, et de chiffrer le disque pour sécuriser le tout.
Bon après il y a le soit-disant problème d’interface chaise-clavier qui se résous très simplement en évitant de demander à l’utilisateur de ne pas faire de choix de sécurité basé sur des informations incompréhensibles… à la fin, vous obtenez une plateforme d’exécution sécurisée pour les applications, reste à sécuriser les applications Web… (c’est pas gagné…)
Control Flow Integrity on LLVM – team ANSSI
« J’espère que vous aimez les compilateurs », le ton est donné. PICON c’est un outil qui fait du CFI, en gros ça sort le graph de flot de contrôle d’un programme, et ça vérifie à l’exécution que le programme suit bien le chemin d’exécution prévu, sinon on le tue ! Bien entendu, ça part du principe que le programme est durci, et que les binaires exécutés sont bien les bons.
Dans un programme, les appels de fonction, les retours de fonction et les appels dynamiques sont des points à surveiller quand on veut s’assurer que le flot d’exécution n’est pas détourné par du ROP. Un peu tout le monde se met à faire du CFI sur des sauts indirects, mais pas forcément sur les parties retour de fonction. Les solutions existantes sont donc pour la plupart incomplètes. Ces compromis sur la couverture sont là pour des raisons de performances. Du coup, on s’en fout si c’est lent, on va essayer de tout protéger (secure lagging ?).
Pour effectuer ce monitoring, on va instrumenter le code en ajoutant de la signalisation pour pouvoir en suite monitorer ces signaux et valider que le flot d’information suivi est le bon, sinon on kill le process.
Bon pour l’instrumentation, c’est la galère, parce-qu’il faut s’assurer que le compilo ne viens pas virer le code de monitoring lorsqu’il fait des optimisations (inlining de fonctions, etc…). D’où l’utilisation de LLVM. la suite par ici sur le github de l’ANSSI
Triton: Framework d’exécution concolique
un projet supervisé par le LaBri, et sponsorisé par Quarkslab. Triton est un moteur d’exécution concolique basé sur PIN et Z3.
Pour savoir ce que contrôle l’utilisateur, on utilise une analyse de teinte qui viens tracer ce qui est influencé par les actions utilisateur. Triton fournis donc un ensemble de fonctions et de callback pour venir teinter des registres ou des zones mémoires, puis effectuer des contrôles sur cette teinte (Ex: un registre donné est influencé par un autre).
Pour connaitre quelles sont les conditions qui influencent l’exécution, on s’aide de la trace et de la teinte pour déterminer ces conditions. Ces conditions sont déterminés à partir d’une représentation symbolique de chaque étape de la trace sous forme de formules SMT-2. La résolution de cet ensemble de formules par Z3 permet de déterminer les conditions influençant l’exécution. Les bindings python de triton permettent d’accéder à ces expressions symboliques générés à partir des instructions exécutés.
Le lien entre les entrés utilisateurs et les conditions identifiés sur la trace est effectué à l’aide de la teinte. Lorsqu’une valeur est contrôlée par l’utilisateur, on remplace cette valeur par une inconnue (genre X). Du coup, pour savoir si le flot de contrôle de l’application est contrôlable par l’utilisateur, on bazarde à Z3 le problème, qui va pouvoir déterminer si une valeur de X permet de modifier le flot d’exécution.
Pour pouvoir tester la solution fournie par Z3, triton gère un système de « snapshots » pour restaurer l’état du programme et le re-exécuter, pour voir si la solution provoque bien un changement dans la trace d’exécution.
Triton fournis des bindings python pour du solving, de la génération de SMT et l’utilisation de fonctions de PIN (on apprécie la simplification), etc… Enjoy !
REbus – un bus de com pour la coopération entre outils d’analyse de sécurité.
L’idée c’est de combiner des outils d’analyse et de les enchainer dans un workflow. L’idéal serais de re-utiliser des outils existants, et ça de façon intelligente. Le rêve ça serais que ça s’orchestre tout seul sans que ça devienne une usine à gaz.
A chaque fois qu’on ajoute un outil dans un framework, il faut modifier le workflow, et c’est le bordel. L’idéal c’est d’avoir un petit bout de workflow associé à chaque outil, et c’est au framework de reconstituer le workflow à partir des outils disponibles, et des éléments en entrée. D’ou l’utilisation d’un bus (type dbus) pour interconnecter les outils.
Un élément analysé s’accompagne d’un descripteur qui contiens les métadonnées, et qui accompagne le binaire à analyser d’un agent à l’autre. Chaque agent choisit de traiter ou non le fichier à partir des métadonnées. Une fois son travail effectué, il enrichis les métadonnées, ce qui permet d’enchainer les traitements.
Quelques exemples d’agents ici
Abyme: Hyperviseur Recursif
Est-il possible d’hyperviser n-fois le même code ? Quel est l’impact sur les performances ? Quelle taille consomme les structures dédiées à la virtualisation ? Voila les questions qui taraudent les orateurs. Les orateurs détaillent les problématiques qui se posent lorsqu’on souhaite virtualiser les opérations privilégiés de l’hyperviseur (instructions vmx).
Vous vous en doutez, les perfs sont pas toujours terribles, mais ça fonctionne.
Stratégies de défense et d’attaque des consoles de jeux vidéos
Les consoles de jeux-vidéos peuvent être très instructives en terme de stratégies de sécurisation. Sur la PS1, c’est pas vraiment de la sécurité, mais une stratégie de zonage des jeux-vidéos, pour éviter que les copies fonctionnent. Les infos de zonage était présentes sur les bords de guidage du CD-Rom, rendant impossible l’inscription de ces informations lors d’une copie « classique ». Du coup les pirates ont utilisé des modchips pour désactiver la fonction de contrôle. Le modchip est devenu un mode d’attaque traditionnel dans les consoles.
La xbox implémente beaucoup plus de protections, binaires signés, contrôle d’accès au disque dur, boot sécurisé via une puce… le problème c’est que l’espace de stockage du boot hard coûte cher, du coup ils ont du économiser, et toute la bootrom n’est pas stockable dans cet espace. La « chaîne de confiance » du démarrage contiens donc un maillon faible. Il s’agit là de la transmission en clair de la bootrom sur le bus hypertransport (jugé trop rapide pour être écoutable). Grâce à des vulnérabilités logicielles dans cette bootrom, la chaîne de confiance pouvait être brisée.
La Xbox360 ajoute elle une vraie architecture de confiance, avec un co-processeur cryptographique qui vient effectuer des contrôles d’intégrité. En jouant sur la taille des @ mémoires bien plus grandes que la taille de la ram allouable dans la Xbox360, il est possible de savoir si une zone mémoire est intègre et chiffrée ou pas. Elle embarque en plus un hyperviseur minimaliste, et elle fait des checksums sur les zones critiques de la mémoire contenant le code du système d’exploitation. Elle contient aussi des « fusibles materiels » pour empécher le « downgrade » du système de la console, lié à des clefs cryptographiques stockés dans le CPU. Les attaques sur la console se sont fait à base de timing attack exploitant une vulnérabilité dans le jeu king-kong. Le mécanisme de patch et d’anti-downgrade à forcé les attaquants à passer à des attaques par injection de faute sur un CPU à 3,6Ghz (il faut être rapide 🙂 ).
Les concepts intéressants: Hyperviseur minimaliste, chaîne de boot sécurisée, contrôles d’intégrité, c’est plutôt balèze, on à pas ça sur tous nos pc.
La PS3 utilise des composants de boot spécifiques comme racine de confiance du boot, le reste se fait par vérification de signatures. Sony n’a pas utilisé de e-fuse pour l’anti-downgrade, ce qui aura des conséquences catastrophiques sur la sécurité. Les communications sur le bus sont chiffrés, empêchant les attaques par DMA. L’hyperviseur ne contient pas lui de fonctions de sécurité aussi bonne que celles de la Xbox360.
Pour conclure, pas d’économies possible en terme de sécurité, le maillon faible est toujours celui ciblé par l’attaquant. Le hard et le soft doivent être bien pensés ensemble pour que la sécurité soit cohérente, et la défense en profondeur n’est pas à négliger.
Rétro-Ingéniérie matérielle: cas d’un DD Chiffré
Plusieurs cas d’epic-fail existent avec des disques pseudo-chiffrants, et du coup il arrive à Airbus d’étudier ces solutions pour en évaluer la robustesse. L’objectif de cette présentation, c’est de présenter la méthodologie d’analyse d’un matériel de ce type.
Déjà on vérifie si ça chiffre, analyse statistique, contrôle d’absence de mode ECB, vérifier que la clef de chiffrement est dérivée du PIN et non lié au boitier, etc… En changeant le disque dur de boitier, les orateurs on pu déchiffrer leur données avec le même code PIN, il est donc envisageable de bruteforcer le code PIN à partir des informations présentes sur le disque dur dans un secteur réservé.
Pour cela, il faut réussir à récupérer le firmware du disque dur. Du coup, les orateurs ont étudié le PCB à la recherche de flash, et il ont recherché les pistes qui connectent les composants. En payant beaucoup de cafés, Ils ont obtenu des photos au microscope de grande résolution et une image rayon X du PCB. La flash est dumpable via SPI (youpi!), mais leur contenu était chiffré.
Du coup, pas le choix, il faut utiliser un analyseur logique pour capturer le code du firmware qui doit bien transiter quelque-part sur un des bus de données.Bon, toujours pas de firmware en clair 🙁 Par contre lorsque le pin saisis est valide, un bloc de donnée est écrit à une @ spécifique, et ça ressemble à un truc lié à la crypto du disque. Bon, bah après plein d’attaques, c’est le FAIL, la sécurité du disque repose donc sur la sécurité du firmware chiffré.
CLIP – OS Linux Sécurisé multi-niveaux
La virtualisation légère par conteneurs est la brique de cloisonnement la plus utilisée au cœur de CLIP. Les privilèges sont réduits visa les capacités Linux. Cette fonction de cloisonnement permet de faire du multi-niveau: deux niveaux de sensibilité. Le niveau bas qui accède au réseau normal, et le niveau haut qui accède au réseau via un tunnel sécurisé. Chaque niveau possède son propre environnement, et ses propres applications.
Le cloisonnement de l’affichage ou du réseau n’est pas un problème trivial. X11 est bien connu pour ça… Les accès matériels et aux supports amovibles sont aussi source de problèmes pour l’isolation. L’isolation au niveau réseau se fait simplement. X11 est isolé et peu privilégié. Chaque cage s’appuie sur un VNC pour l’affichage, et le rendu X11 n’est qu’un client de visualisation VNC des deux serveurs. Concernant les périphériques, la carte son est utilisé de façon commuté, alsa a été modifié pour ce faire.
La gestion des supports amovibles qui sont initialisés avec une signature spécifique, et du chiffrement en option. Il est possible de monter tout les supports avec certains n’étant accessible qu’en lecture au niveau haut, et en lecture/écriture au niveau bas.
Un énorme travail sur le cloisonnement, la gestion des privilèges à été fait, avec une application quasi totale de W xor X sauf pour les mises à jour. La mise à jour se fait obligatoirement via le niveau haut. Les mises à jour sont atomiques, réversibles et résistantes aux interruptions. Il y a toujours deux versions de partitions comme dans l’embarqué, pour avoir sous la main un système toujours bootable.
CLIP n’est pas disponible tel quel, et c’est pas prévu pour devenir une distribution « générique ».
Injection de commandes vocales sur ordiphone
Injection silencieuse de commandes vocales sur smartphone, voila qui est intéressant… Les interfaces vocales sont de plus en plus répandues, siri, ok-google, cortana, etc… Du coup par la voix on peut faire plein de choses sur le smartphone, SMS, surf sur le net, voir changer certains paramètres du téléphone.
Les interfaces vocales se lancent soit via mot-clef, soit via une application, soit par une interface matérielle (bouton home, écouteurs, etc…). Certaines commandes sont traités en local, mais la plupart sont traités dans le cloud. Le câble des écouteurs est souvent utilisé comme antenne de bande FM. Le signal micro est filtré par un filtre passe-bas avant amplification. Du coup on peut en émettant sur cette bande de fréquence comme porteuse et en la modulant, on peut générer du son dans le micro du casque. Bon, la puissance d’émission est limitante… 2m pour un attaquant à pied, 5m pour un attaquant avec un camion. L’attaque ne produit aucun bruits dans le casque de l’utilisateur.
RowHammer
la SRAM coûte chec et sert aux mémoire cache dans les processeurs, et la DRAM elle se décharge et à besoin d’être rafraîchie régulièrement. L’accès se fait par ligne, et chaque ligne lue se doit d’être rafraîchie juste après. Quand on lit des données en mémoire, il se peut que ça décharge des condensateurs d’une ligne à coté, provoquant le flip de certains bits. L’attaque RowHammer consiste à mapper à fond des pages mémoires pour provoquer des bit flip (plus de détails ici).
FlexTLS: des prototypes à l’exploitation de vulnérabilités dans TLS.
TLS est utilisé pour sécuriser des communications sur internet. Il fait l’objet de nombreuses atttaques comme BEAST, CRIME, Heartbleed, FREAK, Logjam. Du coup, comment peut-on sécuriser TLS ? Pour ça, il faut un framework pour implémenter rapidement une nouvelle variante de TLS avec de nouvelles options, ou créer de nouvelles attaques en jouant sur certains messages, leur ordre, etc…
FlexTLS est basé sur miTLS, une implémentation formellement vérifiée de TLS. FlexTLS est implémenté en F#, le OCaml du .NET. Du coup avec FlexTLS, on peut rapidement prototyper des handshakes TLS, et de les challenger.
FlexTLS à permis de découvrir des vulnérabilités dans les stack Java (attaque SKIP).