Cela fait plusieurs mois que je travaille sur des méthodes de cassage de mot de passe améliorées (enfin, j'essaie), et je suis arrivé à un outil plutôt performant et relativement simple dont je ne vais pas diffuser le code de suite. Pourquoi ? Eh bien tout simplement car j'ai dans l'optique de le présenter dans un avenir proche, mais surtout de le tester abondamment. Et pour cela, j'ai mis au point un système de robot twitter offrant un système de cassage de mots de passe basé sur cet outil.
Hashbot, kezako ?
Pour l'occasion, je me suis lancé dans le développement d'un bot twitter, car je n'avais pas forcément envie de monter un site pour l'occasion, et pour plein d'autres raisons: * je n'avais pas envie de mettre de CAPTCHA * je voulais en même temps assurer une diffusion des résultats * je comptais tenir informé via un compte twitter de l'avancée de ce petit projet
Bref, Twitter imposant ses propres limites et ses fonctionnalités, j'ai jugé que c'était un moyen original et à faible coût pour réaliser une interface. Je suis donc parti sur l'idée d'un bot à qui l'on pourrait fournir des hashes MD5, voire même des URLs pointant vers des hashes MD5, qui les ajouterait à une liste de hashes à casser et posterait le résultat sur Twitter. En gros, un robot connecté pilotable par les utilisateurs.
Afin de conserver un bon ratio de cassage de mot de passe, j'ai opté pour un système en cycle. Le principe est simple: le robot collecte toutes les heures les hashes transmis par les utilisateurs, et lance une session de cassage d'une heure. A la fin de celle-ci, il communique les résultats s'il y en a. Bien sûr, plus il y a de personnes à l'utiliser mieux c'est, et à l'heure où j'écris ces lignes il n'y a pas foule à suivre @h4shb0t.
Les résultats sont actuellement postés sur le pastebin de archlinux.fr, mais pourront bouger par la suite.
Implémentation
Le code principal de Hashbot repose sur la bibliothèque Python implémentant une interface à l'API Twitter, j'ai nommé python-twitter. Cette API permet, moyennant des clés d'accès au service, d'accéder aux tweets d'utilisateurs l'ayant installée (c'est le cas pour @h4shb0t) et de réagir en fonction.
Le bot est structuré en deux threads séparés, l'un réalisant la collecte des hashes tandis que l'autre prend en charge les sessions de cassage, et l'envoi des résultats. La phase de cassage est assurée par un outil en ligne de commande, dont le résultat est analysé par le code Python et ensuite envoyé sur un pastebin. Le tout n'est pas anonyme, mais disons que @h4shb0t contribue aussi à peupler la grande base de données de clairs connus (a.k.a. known plaintexts, mais c'est aussi pour ça que certains utilisateurs le suivent sans envoyer de hashes).
Ok, comment on s'en sert ?
Pour demander à @h4shb0t de casser un ou plusieurs hashes MD5, rien de plus simple: * Suivez @h4shb0t sur Twitter (histoire de recevoir les notifications de résultats), * Tweetez à @h4shbot (mention) un ou plusieurs hashes MD5, ou mieux au moins une URL pointant sur un fichier contenant un ou plusieurs hashes MD5, * Attendez l'annonce de @h4shb0t indiquant la bonne réception des hashes et le démarrage d'une session de cassage (toutes les heures)
<emb140|center>
<emb141|center>
Pour le moment, @h4shb0t n'envoie pas de messages direct (DM), par peur de représailles de la part de Twitter. Cependant, l'idée de monter un petit site synthétisant les requêtes ainsi que le taux de réussite et les différentes sessions de cassage semble intéressant.
Depuis ma dernière présentation publique concernant Android (c'est-à-dire depuis la Nuit du Hack 2011, pfiou), beaucoup de personnes m'ont demandé s'il était possible d'envoyer des SMS de classe 0 sur les dernières versions de cet OS. Personnes auxquelles j'avais répondu à l'époque que la démonstration avait été réalisée sur la version 2.1, et que l'astuce ne fonctionnait plus sur les versions récentes. Néanmoins, l'idée de chercher un moyen de le faire sur les version supérieures à 2.1 me trottait en tête depuis ce temps, mais j'avoue ne pas avoir pris le temps de m'y intéresser. Jusqu'à très récemment.
SMS de classe 0: rappels
Lors de ma précédente présentation, j'avais démontré la facilité avec laquelle on pouvait créer des SMS à partir du PDU (Protocol Description Unit) et comment on pouvait se servir de cette fonctionnalité pour transformer un SMS classique en SMS de classe 0. Pour rappel, un SMS de classe 0 est un message particulier qui est destiné à s'afficher "de force" par le téléphone qui le reçoit, généralement utilisé par les opérateurs pour envoyer des notifications critiques aux utilisateurs de leur réseau ou tout simplement pour communiquer directement avec la SIM (via des systèmes peu documentés).
Ainsi, pour envoyer un SMS à partir du PDU correspondant, il fallait modifier la visibilité d'une méthode du SmsManager (sendRawPdu) afin de pouvoir l'appeler, sous réserve de posséder les bonnes permissions. Il s'agissait en fait d'une fonctionnalité offerte par le SDK Android, qui n'était pas directement exposée mais qui était toutefois présente. Cela était valable jusqu'à la version 2.1 du système. A partir de la version 2.2, le SDK a radicalement changé (du moins en ce qui concerne l'envoi de SMS), et cette méthode a disparu: impossible d'envoyer des SMS "craftés" à partir de PDUs ! Damned. Rien sur Internet expliquant comment le faire, et le code est un brin indigeste.
Services systèmes d'Android
Un jour, j'ai pris mon courage à deux mains et décidé de plonger dans le code du SDK [2], qui de fait est opensource et librement consultable, afin de trouver un moyen d'envoyer (de nouveau) ce type de message. Et par extension d'être capable de faire joujou avec les PDUs, comme au bon vieux temps. Et là, le drame: plus aucune référence de "PDU" dans les éléments offerts par le SDK. Le vide. Vraiment rien ? Eh bien après quelques recherches plus poussées, j'ai pu identifier une classe offrant une méthode nommée sendRawPdu, mais appartenant au package com.android.internal.telephony. En cherchant à savoir où elle était appelée, je suis remonté jusqu'à la classe com.android.internal.telephony.IccSmsInterfaceManager, qui propose des méthodes permettant l'envoi de messages (mais pas de PDU) et qui hérite de ISms.Stub. Attendez, "ISms", serait-ce une interface ? Jetons-y un œil.
Il s'agit effectivement d'une interface munie d'un Stub qui sert principalement de wrapper de service, tel que précisé dans la documentation:
<quote>Interface for applications to access the ICC phone book. The following code snippet demonstrates a static method to retrieve the ISms interface from Android:
private static ISms getSmsInterface()
throws DeadObjectException *
IServiceManager sm = ServiceManagerNative.getDefault();
ISms ss;
ss = ISms.Stub.asInterface(sm.getService("isms"));
return ss;
*
</quote>
Il y est fait mention d'un ServiceManagerNative, qui gère des services. En réalité, c'est un service natif qui gère l'envoi des SMS, appelé au travers d'une couche bien définie de classes permettant de vérifier les permissions et de structurer le message à envoyer. Il existe d'ailleurs d'autres services que ce "isms": "phone","content", etc ... L'utilisation de services permet de cloisonner les fonctionnalités mais surtout de limiter les fonctions exportées: l'interface restreint leur usage et complique l'implémentation d'autres fonctionnalités.
Là où ça devient intéressant, c'est que la classe SMSDispatcher est instanciée par la classe `IccSmsInterfaceManager <http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.7_r1/com/android/internal/telephony/IccSmsInterfaceManager.java?av=f>`_, et il semble donc possible de pouvoir récupérer une instance de cette classe. J'ai de suite pensé l'instancier via l'application, mais un problème est survenu: le contexte d'instanciation n'est pas bon. Seule une instance de la classe com.android.internal.telephony.Phone peut retourner l'instance unique et utilisable d'IccSmsInterfaceManager, via la méthode getIccSmsInterfaceManager. Et c'est là que ça se complique.
Récupération de l'instance système Phone
Le problème reste entier: sans une instance de la classe Phone, impossible d'atteindre une instance de SMSDispatcher, on peut donc oublier l'envoi de SMS via PDU. Cependant, une classe offre la possibilité de récupérer l'instance Phone courante: PhoneFactory. Cette classe est encore une fois interne et n'est pas exposée via le SDK "standard" offert par Google. Elle offre une méthode getDefaultPhone() qui retourne une instance de Phone, avec toutefois un bémol: un appel à cette méthode ne réussit que si le code appelant est exécuté au sein du processus com.android.phone, le processus dédié (et unique) à la gestion de la téléphonie sur le smartphone. Et un souci de plus.
Pour pouvoir exécuter du code dans le contexte du processus com.android.phone, il faut que l'application respecte les contraintes suivantes: * elle doit être signée avec le même certificat que l'application créant le processus com.android.phone * le manifest doit spécifier le processus dans lequel une application, activité ou service va s'exécuter
Par conséquence, notre application doit être une application système (com.android.phone étant mis en place par le système, et signée avec le certificat système) et doit forcer son code à être exécuté dans le contexte de com.android.phone. Heuu, ça s'annonce difficile.
Plusieurs questions se posent: * Comment créer une application système ? * Comment exécuter une activité dans le contexte du processus com.android.phone ?
Une fois ces questions résolues, l'appel de sendRawPdu sera un jeu d'enfant.
Création d'une application système
Nous allons devoir créer une application système, cela implique plusieurs choses: * être capable d'utiliser tous les éléments du SDK Android, et notamment les classes internes (com.android.internal.*) * être capable de signer l'application de manière à ce qu'elle soit reconnue comme application système * être capable de l'installer sur un smartphone
L'élément le plus bloquant pour la création d'application système reste la phase de signature de l'APK: celui-ci doit être signé avec le même certificat que les autres applications systèmes. Sur une version Android standard, c'est quasi impossible à moins d'avoir la clef privée. Par contre sur des mods d'Android comme CyanogenMod, la clef privée du certificat est publique et peut être utilisée pour signer une application et l'installer comme application système sur une rom CyanogenMod.
Le développement avec Eclipse est plus sport, la version du framework Android (android.jar) fournie dans le SDK ne contient pas les APIs internes. A moins d'utiliser la réflexion Java à gogo, s'interfacer avec les APIs internes est impossible en l'état. C'est ce que je pensais jusqu'à ce que je tombe sur ce tutorial très bien fait, expliquant comment intégrer dans le fichier android.jar les classes internes récupérées grâce à jd-gui, et comment patcher le plugin ADT afin d'autoriser l'utilisation des APIs internes. Il est assez bien fait, mais je vais vous donner une méthode plus rapide pour arriver au même résultat.
Premièrement, il vous faudra télécharger les différentes versions du SDK Android qui incluent les classes internes, qui sont disponibles sur github. Ensuite, pour chaque dossier dans le SDK, copier le contenu dans un dossier avec pour nom android-X-internals, et insérer dans chacun d'entre eux les fichiers issus de github:
# cd <SDK>/platforms # cp -rf ./android-7 ./android-7-internals # cp -rf ./android-8 ./android-8-internals # cp -rf ./android-9 ./android-9-internals # cp -rf ./android-10 ./android-10-internals # wget "https://github.com/inazaruk/android-sdk/tarball/master" -O /tmp/platforms.tgz # tar xvzf /tmp/platforms.tgz
Il ne reste plus qu'à patcher le plugin ADT, tel qu'indiqué sur cette page. Une fois cela fait, relancer Eclipse et vous devriez voir apparaître de nouvelles versions du SDK d'android, avec un numéro de SDK négatif ...
... ainsi que la restriction sur les APIs internes, qui doit être patchée (com/andoird/internax/* à la place de com/android/internal/*):
Une fois notre application développée, nous allons pouvoir la signer et l'installer sur notre smartphone (utilisant CyanogenMod si vous avez suivi):
# signapk.sh MonApp.apk /tmp/MonApp-signed.apk # adb shell mount -o rw,remount /system # adb push /tmp/MonApp-signed.apk /system/app
J'utilise signapk.sh, un script basé sur signapk.jar et les certificats de CyanogenMod (Gingerbread, CM 7.2). Ce script effectue basiquement la commande suivante:
java -jar signapk.jar platform.x509.pem platform.pk8 Application.apk Application-signed.apk
Après cette dernière étape, notre application système sera installée et reconnue par Android en tant que tel. Bon, reste à développer une application d'envoi de SMS classe 0 maintenant que l'on possède un IDE et un SDK améliorés.
Utilisation de la réflexion pour l'envoi de SMS via PDU
Faisons le point. On a un éditeur Eclipse avec ADT patché et au moins un SDK qui intègre les classes com.android.internal.*. On sait aussi déployer une application système. Au boulot.
Pour commencer, on récupère l'instance de Phone (supposons que cela soit exécuté dans le bon processus, ce point sera abordé par la suite):
Phone phone = PhoneFactory.getDefaultPhone();
Puis on récupère une instance de IccSmsInterfaceManager:
f = IccSmsInterfaceManager.class.getDeclaredField("mDispatcher");
f.setAccessible(true);
SMSDispatcher sms_disp = (SMSDispatcher)f.get(ismsm);
Et on utilise un brin de réflexion Java pour appeler la bonne méthode, en transformant au passage un message SMS classique en SMS de classe 0 (via la manipulation des PDUs)
byte[] b = new byte[0];
SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
null, phoneNumber, message,false
);
/* change class to Class 0 */
size = (int)pdus.encodedMessage[2];
size = (size/2) + (size%2);
pdus.encodedMessage[size+5] = (byte)0xF0;
/* send raw pdu */
Method m = SMSDispatcher.class.getDeclaredMethod("sendRawPdu", b.getClass(), b.getClass(), PendingIntent.class, PendingIntent.class);
m.setAccessible(true);
m.invoke(sms_disp, pdus.encodedScAddress, pdus.encodedMessage, null, null);
Et voilà, rien de bien compliqué niveau code. Une fois le tout assemblé avec la gestion des exceptions:
/* Sends class 0 SMS */
private boolean sendSMS(String phoneNumber, String message)
*
int size;
Field f;
SMSDispatcher sms_disp;
Phone phone = PhoneFactory.getDefaultPhone();
/* Get IccSmsInterfaceManager */
IccSmsInterfaceManager ismsm = phone.getIccSmsInterfaceManager();
try {
f = IccSmsInterfaceManager.class.getDeclaredField("mDispatcher");
f.setAccessible(true);
sms_disp = (SMSDispatcher)f.get(ismsm);
if (sms_disp != null)
{
byte[] b = new byte[0];
SmsMessage.SubmitPdu pdus =
SmsMessage.getSubmitPdu(
null, phoneNumber, message,false
);
/* change class to Class 0 */
size = (int)pdus.encodedMessage[2];
size = (size/2) + (size%2);
pdus.encodedMessage[size+5] = (byte)0xF0;
/* send raw pdu */
Method m = SMSDispatcher.class.getDeclaredMethod("sendRawPdu", b.getClass(), b.getClass(), PendingIntent.class, PendingIntent.class);
m.setAccessible(true);
m.invoke(sms_disp, pdus.encodedScAddress, pdus.encodedMessage, null, null);
return true;
*
else
return false;
} catch (SecurityException e) *
return false;
* catch (NoSuchFieldException e) *
return false;
* catch (IllegalArgumentException e) *
return false;
* catch (IllegalAccessException e) *
return false;
* catch (NoSuchMethodException e) *
return false;
* catch (InvocationTargetException e) *
return false;
*
}
Exécution dans le contexte de com.android.phone
Le cœur du système d'envoi est développé, il ne reste plus qu'à préciser le manifeste de manière à ce que l'application soit lancée dans le contexte du processus com.android.phone. J'ai fait beaucoup de tests, et la seule configuration qui semble passer est la suivante, basée sur un identifiant d'utilisateur partagé android.uid.system et sur la définition du processus dans lequel l'activité ZeroSMS doit s'exécuter:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.zerosms"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="android.uid.system">
<uses-permission android:name="android.permission.SEND_SMS"/>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ZeroSMS"
android:label="@string/app_name"
android:process="com.android.phone">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Il ne reste plus qu'à compiler et produire un APK non-signé, qui sera ensuite signé avec signapk, et installé avec adb, comme mentionné précédemment. Une fois installée, l'application permet l'envoi de SMS classe 0. J'ai publié le code de l'application ainsi qu'une version compilée et signée sur Github [1]. Je ne vous fait pas de démo, mais je vous laisse essayer l'APK final (ZeroSms-signed.apk, situé dans le dossier apks). L'application ressemble à ceci:
<center><img131><img132></center>
Quid des permissions ?
Durant mes tests (qui m'ont pris plusieurs jours) j'ai eu des difficultés à arriver à la solution décrite dans cet article, et j'ai pu notamment remarquer que le fait de passer par l'envoi de PDU contourne les restrictions (via les permissions) sur l'envoi de SMS. J'ai eu énormément d'erreurs de type "User 1001 has no permission android.permission.SEND_SMS", ce qui m'a bloqué pendant quelque temps, jusqu'à ce que je trouve cette parade (passer par la classe SMSDispatcher). Cela contourne notamment les vérifications faites par la classe IccSmsInterfaceManager sur la permission android.permission.SEND_SMS. Ceci dit, vu que l'application est une application système, cela ne remet pas en cause la sécurité d'Android (l'application étant installée de force via adb), mais offre un moyen de contourner les vérifications effectuées sur certaines permissions.
Conclusion
Je dois avouer que les manipulations à effectuer sur la version 2.1 et celles présentées ici sont franchement différentes et bien plus complexes sur les SDK récents. Cependant, une fois le SDK Android amélioré et le plugin ADT d'Eclipse patché, le développement est très intuitif et permet de jouer pleinement avec les composants système: téléphone, sms, etc ... Je suis sûr que ça peut ouvrir des voies vers d'autres utilisations !
Notez toutefois que l'application peut être signée pour les différents mods Android populaires, bien que dans mon exemple je l'ai fait pour CyanogenMod 7.2. Cette astuce doit fonctionner sur les versions récentes d'Android, toutefois ne disposant pas d'un téléphone sous ICS je n'en ai pas la certitude, si quelqu'un peut confirmer ça serait super.
MAJ - 12/10/2012
Versions compatibles (suites aux retours de lecteurs): * CyanogenMod version 7.2 * CyanogenMod version 9 * CyanogenMod version 10
References
`1] [ZeroSMS sur Github <https://github.com/virtualabs/ZeroSMS>`_
`2] [Code source Android 2.3.7 (Grepcode) <http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/2.3.7_r1/>`_
J'ai rendu visite il y a quelques jours à de la famille en Corrèze, terre de prédiléction de notre cher Président, et j'ai pu voir le superbe ordinateur portable que le Conseil Général de Corrèze a prêté à mon petit cousin dans le cadre de l'opération «Ordicollège 19». J'avais entendu parler de cette opération dans les médias, et j'étais donc content de pouvoir toucher à un des ordinateurs portables prêté à un élève. Les nouveaux collégiens corrèziens se voient ainsi tous dotés d'un ordinateur portable, enfin maintenant d'une tablette numérique iPad (depuis 2010).
Tâtons la bête
J'ai ainsi pu manipuler l'engin: un portable de marque Asus (c'est du solide), qui tourne sur Ubuntu. Je n'ai pas forcément pris le temps de regarder la version, mais de mémoire il me semble que c'était à jour. J'ai dans un premier temps tapé quelques commandes, histoire de voir ce qu'il y avait dessus, mais rien de bizarre:
Puis je me suis intéressé à une fonctionnalité typique d'Ubuntu: le sudo su. Mon cousin m'ayant dit que la configuration de l'ordinateur portable ne devait pas être modifiée, règle stipulée dans l'accord de prêt par ailleurs, je m'attendais à ce que cette commande échoue. Eh bien non, je me suis retrouvé administrateur de la machine, avec un bon vieux shell root. Bien sûr, il m'a fallu saisir le mot de passe du compte utilisateur, qui n'est autre que ordico. Mon cousin m'a par ailleurs fait remarquer que les élèves étaient autorisés à changer leurs mots de passe, mais que le système réclamait un mot de passe complexe, et donc que personne ne le changeait.
Par curiosité, j'ai récupéré le contenu du fichier /etc/shadow, histoire de trouver le mot de passe du compte d'administration root. Il m'a fallu peu de temps et une wordlist sur mesure pour arriver à le casser, ceci dit je n'ai pas été déçu. Le mot de passe du compte d'administration n'est autre que ... «ordicollege». Tadaaaa ! Donc bon, au lieu de faire un sudo su on pourrait tout aussi bien faire un su. Ce qui est révélateur dans le cas présent, c'est la contradiction entre la volonté d'empêcher les élèves de modifier le système et l'idée naïve qui consiste à mettre un mot de passe bateau. Difficile dans ce cas de limiter les modifications des systèmes.
Au vu de la progression de popularité des distributions orientées grand public comme Ubuntu, il semble probable qu'une faible proportion des élèves soient un brin connaisseurs ou asseaz curieux pour aller bidouiller le contenu de cet ordinateur mis à disposition, pour y installer des jeux, wine ou autres. J'ai d'ailleurs pu voir DeSmuME (logiciel d'émulation de jeux Nintendo DS) installé sur cet ordinateur portable ... Car oui, les dépôts utilisés sont ceux officiels, là encore je m'attendais au moins à des dépôts maison et centralisés au niveau du Conseil Régional, mais non. Décidémment, la tâche des bidouilleurs en herbe est très facilitée.
Quelques remarques techniques liés à l'opération «Ordicollège»
Une fois rentré, j'en ai profité pour me renseigner sur cette opération, après avoir récupéré l'avis d'un élève. L'opération a été lancée en 2008, et chaque élève de 6ème a reçu entre 2008 et 2010 un ordinateur portable. Elle a été continuée en 2011 et 2012, mais cette fois-ci ce sont des iPads qui ont été mis à disposition (version 1 pour les élèves arrivés en 2011, version 2 pour ceux arrivés en 2012). Un site officiel a été déployé, ainsi qu'une plateforme web de suivi et de maintenance. Pour le coup les informations présentes sur le site officiel de l'opération contiennent du poney en barre. Quelques extraits choisis:
Les premiers et second points peuvent se comprendre, mais peuvent dans la plupart des cas exposer des élèves à des vulnérabilités critiques, et donc exposer de même leurs données personnelles. Toutefois, si les iPads sont administrés comme le sont les ordinateurs portables, je ne pense pas que cela pose de gros problèmes: beaucoup de parents qui possèdent un iPad et qui l'ont jailbreaké peuvent le faire, et ceux qui s'y connaissent en Linux peuvent aussi altérer le contenu de l'ordinateur. Pour le retour à la plateforme, les opérations sont réversibles donc difficile pour un technicien de déterminer ce qui a été fait sur le matériel mis à disposition. Normal, ce ne sont pas des experts en inforensique.
Le dernier point m'a beaucoup étonné, car il est révélateur d'une pratique de la plateforme de maintenance: l'interdiction de création ou de modification du mot de passe de la tablette pour cause de coût de maintenance. Le site mentionne d'ailleurs les raisons de cette interdiction:
<quote>Pourquoi cette interdiction ? Depuis l'arrivée de la tablette dans le dispositif Ordicollège, la première cause d'intervention et d'immobilisation de ces matériels reste la création d'un code de verrouillage et son "oubli" par l'utilisateur. A chaque intervention de ce type, le matériel est immobilisé, les contenus stockés détruits, et cela pénalise à la fois l'utilisateur et la mise en oeuvre de ces outils par les enseignants. Cela engendre les opérations suivantes : prise en charge du matériel, effacement de la configuration, rechargement du système des applications, paramétrage, chargement des applications (valeur 30 €).</quote>
Ce dernier point est cependant très discutable car cela signifie que tout élève qui se fait emprunter sa tablette (ou même qui la prête en cours à un autre élève) ou qui se la fait voler par un autre élève peut voir ses informations personnelles compromises. Et cela peut aller jusqu'à la publication sur Facebook de messages ou photos malvenus, tels que les jeunes le font déjà. Alors oui, alléger les coûts c'est bien (surtout pour une opération ayant un budget de 1,5 M€) mais penser à la sécurité et la protection des informations personnelles de nos chères têtes blondes accros à Facebook et à Internet, c'est quand même vital (rappelez vous Luc Chatel et sa volonté de faire fermer les comptes Facebook des élèves harceleurs).