SSTIC 2017 - J1
Bon bah on est reparti pour le XVème SSTIC dans un amphi plus grand, aux sièges plus larges, mais avec très peu de prises électriques (on peut pas tout avoir hein 😉 ). J’ai quand même pu trouver une prise o/
La nouveauté c’est l’amphi super-grand avec des sièges larges !
(Note aux orateurs: si j’ai écrit une connerie, n’hésitez pas à me le signaler dans un commentaire 😉 )
(edit: wrap-up en anglais sur le blog de @xme)
Conférence d’ouverture – Octave Klaba – OVH
VAC ça viens de VACuum, l’aspirateur, c’est le nom de la solution anti-DDoS. la V2 est basée sur des FPGA, et à une capacité de 160Gbps par port ! du coup en entrée de chaque centre, il y a un VAC capable de nettoyer le traffic avant de le transmettre sur le réseau interne. Lorsqu’on assemble l’ensemble des équipement, OVH à une capacité de 2,5Tbps de traitement de flux à nettoyer.
C’est pas le tout de nettoyer, il faut aussi activer la solution quand un DDoS à lieu, dans les DataCenter il y a deux étages de routage avec le VAC au milieu. C’est très dur de ne pas avoir de faux-positifs pour ne pas activer la solution anti-DDoS quand il ne faut pas, ce qui pénaliserait la performance du client. Détail qui peut vite être galère, l’analyse anti-DDoS n’étant effectuée que sur les paquets entrants, les sortants passant par un autre chemin (ce qui peut s’avérer galère pour les communications UDP). Pour encaisser un gros DDoS, il faut coordonner les VAC pour faire du multi-VAC (moooltivac). Au début ils ont commencé avec les solutions d’ArborNetworks, mais c’était assez cher, et du coup ils ont développé leur solution Anti-DDoS qui fait mieux pour moins cher, afin de protéger tous les clients Gratuitement.
Chaque VAC est composé de plusieurs étages des équipements qui ont une fonction de nettoyage précise. A coup de BGP, le VAC aspire le traffic réseau, puis le route d’un composant à l’autre à coup de plein de techno réseau: DSCP + PBR + BGP + QPPB (dont j’comprend pas le nom, mais ça à l’air vachement bien). Et du coup avec du Quagga et des annonces BGP, le traffic en fonction de sa typologie va emprunter des chemins dans les modules de nettoyage de façon rapide et efficace. Pour nettoyer les paquets SYN, les gros SYN utilisé dans les attaques synflood sont supprimés avec des composants à pas cher. UBRL c’est un QoS spécifique pour les Tradeurs afin que l’accès soit équitable entre les IPs. Normalement, pour que la QoS marche bien, il faut connaitre la liste des ips & bande passante associé, mais avec UBRL, on peut le faire dynamiquement toute les 10ms. Du coup on peut utiliser du UBRL sur tout le DC pour traiter le traffic de DDoS dynamiquement pour beaucoup moins cher qu’une solution ArborNetowrks 30gbps.
Petit passage sur Mirai. 160Gbps, mais avec plus de 300M de paquets par seconde, ce qui est très dur à traiter, ce qui à boosté le developpement du VAC v2 pour encaisser Mirai partout. Coté DDoS, OVH n’ a pas eu beaucoup d’incident sur ses backbones sauf à Madrid, ou OVH à été obligé de communiquer dessus, et de blacklister les IP des cam avec une nullroute. Pour détecter les équipements down, il y a une sonde dans chaque DC qui ping comme une folle les composants. Et à coup de machine learning, ils viennent détecter les anti-patterns, et avec une seconde couche de machine learning, ils viennent trouver les éléments communs au niveau IP entre les composants qui posent problème.
L’administration en silo – Aurélien Bordes
Plus sérieusement, il y a Kerberos, ou là les secrets à protéger sont présent, c’est sur le poste de travail, sur le serveur kerberos, et le protocole d’échange. Kerberos propose un mécanisme de délégation d’authentification qu’il faut absolument interdire au niveau des administrateurs.
Windows propose de nouveaux mécanismes de protection des comptes d’administration (qui sont détaillés dans les actes). Coté client, on peut désactiver la mise en cache des secrets (fini mimikatz). Coté KDC/Controleur de domaine, on désactive le NetLogon, et les protocole crypto pourris. Le blindage kerberos, c’est l’implémentation du protocole FAST pour mieux protéger les échanges d’authentification. Kerberos avec FAST c’est très compliqué, du coup c’est plus sûr. Démo vidéo de la mise en oeuvre de Kerberos armor qui associe des utilisateurs à un ensemble de machines via le TGT de la machine. En utilisant ce principe, on peut mettre en place une politique d’authentification qui empêche un utilisateur de s’authentifier sur une machine qui ne fait pas partie de sa zone. Ainsi, une authentification de niveau vert ne fonctionnera pas sur les machines de niveau jaune. Au niveau de l’accès aux machines, on peut forcer l’utilisation d’une authentification composée ou l’utilisateur DOIT être sur une machine donnée pour pouvoir se connecter (pour plus de détails je vous invite à lire les actes).
WSUS Pendu – Romain Coltel & Yves Le Provost
Pwn d’un réseau windows via Windows Server Update Service. Parfois, en pentest, on croise des réseaux séparés voir déconnectés du coup les pass the hash, ça marche pas. L’idée consiste donc à pwner un serveur WSUS pour pousser une mise à jour malveillante permettant de compromettre un réseau ad-hoc qui récupère ses maj depuis le serveur WSUS compromis. L’orateur nous décrit le fonctionnement de WSUS et le parcours des données de Maj. Les données de mises à jours sont stockés dans du XML, et sont parsés par la BDD WSUS qui va vérifier que les Maj sont bien approuvés par les admin. Ces fichiers XML contiennent le nom des exécutables, leurs paramètres et une signature (en gros). La signature des fichiers de Maj est vérifiée par le serveur WSUS avant de pousser les Maj aux clients WSUS. Coté attaque, la seule publiée consiste à faire un MitM entre le client et le serveur WSUS, le fichier XML ne signant pas les arguments passés en paramètres et utilisant psexec ou pginfo, un binaire gentiment signé par Microsoft (c’est con…). Dans le scénario d’un réseau déconnecté, on ne peut pas jouer de MitM, la solution des orateurs consiste à s’injecter dans le process du serveur WSUS, et à enrichir les maj avec psexec & cie + commandes associés.
Coté protection comment éviter ce type d’attaques: 1) utiliser TLS pour les communications avec le serveur WSUS, ce qui évite les MiTM. Autre solution, pour protéger le serveur WSUS, il vaut mieux le placer en zone rouge, plutôt que sur le réseau jaune.
Coté audit WSUS, les orateurs ont créé un PoC d’audit WSUS depuis la BDD du serveur bientôt disponible sur leur github.
Durcissement système à l’aide de systemd – Timothé Ravier
Le but du jeu, faire une combo entre les sécurités du kernel linux et les fonctionnalités de systemd. Systemd remplace les initscripts et sysVinit par des fichiers de configuration. Par défaut, les services démarrent en root, c’est pas terrible, alors on va cloisonner tout ça et on va interdire a certains services certains syscals via seccomp-bpf. Bon, ce type de durcissements peut parfois oublier un syscall qui permet de bypasser certaines protections, comme dtrace.
Via les capacités linux, on peut donner à certains services des privilèges spécifiques, comme par exemple binder un port <1024 sans être root. On peut aussi jouer sur les mount namespaces pour remonter certaines parties du FS en read-only pour un service donné. Attention là encore à ne pas se mélanger les pinceaux dans les capacités en blacklistant celles qui sont trop riches comme cap_sys_admin.
Landlock – Cloisonnement programmable non privilégié – Mickaël Salaun
Landlock est un mécanisme noyau développé par l’orateur pour faire du sandboxing userland à destination d’applications utilisateur non-privilégés tel que les lecteurs multimédias. Ce ne sont pas les mécanismes de contrôle d’accès qui manquent, mais ils sont réservés aux administrateurs, comme SELinux. D’autres mécanismes de sandboxing comme LXC & cie nécessitent d’être lancés en root avant de dropper les privilèges. Landlock propose un mécanisme de descente de privilèges utilisable sans privilèges root, et sans modification des politiques de sécurité existantes.
Static Analysis and Runtime-Assertion Checking: Contribution to Security Counter-Measures – Dillon Pariente & Julien Signoles
La méthode CURSOR consiste à combiner Frama-C, Value et ACSL. A partir de l’analyse Frama-C, on vient identifier les endroits critiques, et y adjoindre du code de logging afin d’identifier les tentatives d’exploitation. Exemple à partir d’un stack buffer overflow. Frama-C identifie automagiquement les fonctions potentiellement vulnérables et lève des alarmes sur ces fonctions avec les pré-requis nécessaire à leur bon usage. Ensuite on vient remplacer les commentaires d’alarme par du code de contrôle/log supplémentaire. A l’exécution on vient vérifier ces conditions.
BinCAT: purrfecting binary static analysis – Philippe Biondi,Raphaël Rigo,Sarah Zennou,Xavier Mehrenberger
Exemple avec un crackme qui calcule des CRC32 custom à partir des infos saisies, et qui utilise seulement certains inputs, en suite il mélange le tout dans un sha1 qu’il affiche en hexa.
Bincat affiche un panneau complémentaire dans IDA, qui démarre son analyse a partir d’un ensemble d’état initiaux: GDT, Valeur des registres. Quand on ne connait pas les entrés initiales, on peut leur affecter une valeur symbolique « top » qui signifie a l’analyseur que toutes les valeurs sont possibles pour cette entrée. L’outil dispose d’une version simbolique de certaines fonctions très usités comme printf(), et est donc capable de les reconnaitres. IDA n’est pas nativement capable de suivre des appels sur la pile, mais Bincat viens pallier à ça car il possède une représentation symbolique de la mémoire. Il peut donc reconstituer les paramètres d’entrée des fonctions et leurs outputs si elles ont été modélisés.
Autre exemple d’analyse sur le Crackme, en venant teinter les donnés d’entrée comme le nom de l’entreprise. Bincat viens colorer en vert les instructions « touchés » par les donnés d’entrée contrôlés par l’utilisateur. Et comme Bincat possède une version symbolique de sprintf() il peut venir identifier quelles parties de la chaine de sortie de sprintf() sont teintés.
Sous le capot, Bincat est composé d’un plugin python IDA et d’un binaire OCaml qui s’occupe de l’analyse. L’IL de Bincat est généré par un décodeur qui prend les instructions x86 et les transformes en une expression riche tenant compte de tout les effets de bords de l’instruction sur les registres et les flags. Il est délicat de décoder du x86 et de ne rien rater de leur comportement, du coup les sorties symboliques issus de l’exécution de Bincat ont été comparé aux résultats des tests Qemu. Pour chaque fonction appellée dans le binaire, il faut disposer d’une version symbolique de la fonction modélisant ses effets de bord. L’outil est open-source est disponible ici et les sources là.
Désobfuscation binaire : Reconstruction de fonctions virtualisées — Jonathan Salwan,Marie-Laure Potet,Sébastien Bardin
Une protection logicielle à pour but de rendre plus complexe l’analyse d’un programme, tout en conservant ses propriétés fonctionnelles. La virtualisation est une technique d’obfuscation connue qui consiste à re-écrire le programme dans un bytecode propriétaires, et à remplacer la fonction à protéger par un appel a la machine virtuelle avec le bytecode à exécuter. La rétroconception d’une VM, c’est chiant, il faut comprendre la VM, quel sont ses opcodes, etc… puis en suite traduire le bytecode en langage machine classique pour pouvoir désassembler la fonction.
L’orateur s’est fixé pour objectif de retrouver le code d’origine de la fonction à partir du bytecode. La machine virtuelle mêle traces d’exécutions de la VM et traces d’exécution du programme traduit. Pour se faire, l’orateur se base sur une analyse de teinte à partir des inputs de la fonction « virtualisée ». Afin de s’abstraire des effets de bords de la VM, l’orateur viens traduire l’asm en un IL basé sur l’outil TriTon. à partir de cette représentation symbolique et des informations de teinte issue de la trace, on peut extraire une partie de la logique du programme d’origine. Mais il ne s’agit que d’un seul chemin, Du coup pour découvrir d’autre chemins on utilise un smt solver pour parcourir toutes les arètes et découvrir la logique du programme. On extrait en suite cet ensemble de code IR, et via Arybo on le transforme en code LLVM, on exécute les passes d’optimisation -O2 puis on transforme le LLVM en code ASM (et paf ça fait des chocapic).
Pour évaluer sa technique, l’orateur s’est attaqué au challenge Tigress, et l’outil les à tous pété, mais le problème c’est que ça bouffe énormément de RAM. Solution de l’orateur; prenez un gros SSD et mettez un GROS swap. Reste à tester sur d’autres protections, mais ça marche sur VMProtect.
Writing parsers like it is 2017 — Geoffroy Couprie,Pierre Chifflier
Les méthodes formelles etcs, c’est cool quand on crée du code depuis 0, mais quand on à un gros gros legacy, c’est la misère à maintenir. C/C++ c’est dur, les gens font plein d’erreurs, et c’est la galère… Mais, on ne peut pas re-écrire ces projets, la base de code est énorme, et en plus on risque de re-produire les mêmes erreurs. En plus les développeurs peuvent rarement changer de techno sur commande(ou alors ils bossent en ESN). Du coup, il faut concentrer le refactoring sur la zone faible de nos chères applications C/C++: Le parsing ! Rust est un langage ou l’on peut manager la mémoire, avec une gestion de type sûr et des mécanismes de validation. NOM est une librairie de génération de code à base de macro Rust basé sur des concepts de programmation fonctionelle.
Exemples d’intégration de Rust dans un projet C existant: VLC et Suricata. C’est des softs gavé de parseurs, pour plein de protocoles, et il faut le faire proprement, de façon sûre et performante. Création d’un suricata durcis en recodant quelques parsers, notamment TLS. Pour coder un parser, on part des Spec/RFC (et on s’endort…) On part souvent d’un « hello server » et on utilise des slices, les slices en rust, c’est une « vue » sur une zone mémoire sans avoir besoin de copier quoi que ce soit, c’est Rust qui gère. On peut aussi dire à Rust de pas toucher à un buffer, et comme ça on est sûr de pas faire d’use-after-free. Bon lire les paquets, c’est facile, mais quand on regarde la machine à état de TLS, bah c’est l’enfer.
Reste à intégrer votre super-parser dans le projet C, et ne pas se foirer… Là les suites de test disponibles dans les projets viennent aider. Le fuzzing come cargo-fuzz viennent vous aider à trouver ce que vous avez raté.
Exemple avec VLC, un lecteur multi-média très bien découpé ou chaque codec/plugin est une .dll, et du coup l’Orateur s’est dit qu’il suffisait de re-coder l’interface et les parsers en NOM + Rust. Les structure C ça se traduit très bien en Rust, vu que c’est quasi pareil sur les types, chaque type C ayant son équivalent en Rust. Rust-Bindgen permet de générer des bindings et des headers C automagiquement. FLV c’est le format vidéo de flash, et il est bien crado. Point important: quand on est intégré à un code C, on est un invité dans la maison, du coup on peut faire une API sûre, et garantir qu’on va pas faire caca dans la mémoire (TM). On peut faire plus en Rust, mais c’est VLC qui gère l’allocation mémoire, donc il faut respecter son fonctionnement. L’intégration avec le build system se fait très bien avec les autotools, et on peut s’intégrer de façon transparente dans la chaine de compilation.
Ce qui est proposé par les Orateurs, c’est une nouvelle méthodes avec un langage récent qui communique avec un vieux langage en garantissant 0 copie et 0 conversion de données. On peut séparer les parsers et en faire peut-être plus tard comme des librairies de références. ça peut se gluer avec du python, du C/C++, du OCaml.
Les parsers écrits en Rust sont re-utilisables, et on va beaucoup plus vite en Rust pour écrire du code qu’en C parcequ’on élimine la case « debugger ». Coté feedback, les gens ont du mal avec l’aspect strict de Rust, c’est parfois dur à lire, les Macro sont dure à débugger mais ça évite quand même une palanqué d’erreurs.
C c’est pourri, on aimerais bien avoir des bugs nouveaux et pas des trucs des années 70. L’idéal serais d’avoir une communauté de parsers de référence en Rust pour le bien de tous.
caradoc : un boîte à outils pour décortiquer et analyser sereinement les fichiers PDF — Guillaume Endignoux,Olivier Levillain
Quand on veut parser un PDF, il faut commencer par la fin (normal…) et le format gère les évolutions successives du fichiers, en rajoutant une fin à la fin. Vu qu’a la base c’est un format texte, ils ont rajouté la compression. Bon comme c’est chiant sur internet d’attendre la fin du fichier pour le lire, du coup ya aussi un truc en début de fichier pour pouvoir lire la première page, etc… Et du coup, d’un lecteur à l’autre, on à pas le même texte pour le même fichier.
Caradoc est un parser PDF codé en OCaml. En plus de parser le doc, il vérifie la struture arborescente du PDF, et permet de parcourir les objets PDF, même si le typage est très riche(+700 types). plus de doc ici.