Chiffrement des données utilisateurs sous Android

Magazine
Marque
MISC
Numéro
58
Mois de parution
novembre 2011
Spécialité(s)


Résumé

Depuis quelques mois, on voit fleurir sur Internet des alertes de sécurité concernant des malwares, vulnérabilités et fuites d'informations personnelles touchant le système d'exploitation mobile de Google : Android. Il est donc légitime de se demander s'il est possible de sécuriser les données personnelles manipulées par ce système. L'objectif de cet article est de vous présenter la mise en place d'un mécanisme de chiffrement de vos données sur votre terminal Android.


Body

1. Introduction

1.1. Intérêt du chiffrement sur les terminaux mobiles

Bien qu'il ne protège pas contre toutes les formes de fuites de données (transmissions d'identifiants en clair ou de la position de l'utilisateur par des applications), le chiffrement des données stockées sur un terminal mobile se révèle une solution adaptée en cas de perte ou de vol de l'appareil. Il peut, en effet, être problématique pour une entreprise de voir disparaître dans la nature des informations sensibles via ces terminaux pas ou peu sécurisés.

Android a par ailleurs un retard à combler dans ce domaine. L'iPhone d'Apple propose un chiffrement matériel AES 256-bits ainsi que la possibilité de chiffrer les e-mails et les pièces jointes [APPL], tandis que RIM Blackberry chiffre la totalité des données émises par ses appareils à l'aide d'un triple chiffrement DES ou AES 256-bits.

Il est tout de même à noter que concernant l'iPhone, le chiffrement matériel a déjà été partiellement contourné, permettant ainsi de récupérer sur un appareil a priori chiffré des données telles que des clés d'authentification Wi-Fi et des identifiants VPN [IPHO].

La société Whisper Systems, qui a dans un premier temps mis en œuvre une solution de chiffrement des appels, propose à présent un chiffrement de l'intégralité du contenu pour les terminaux Android.

Il s'agit d'un système Android modifié pour intégrer un chiffrement bas niveau des données stockées en utilisant une version modifiée du système de fichiers YAFFS [WHS]. Ce système Android clés en main n'est malheureusement disponible que pour le Nexus S et le Nexus One pour l'instant.

Pour sa part, Google fournit depuis Android 3.0, alias Honeycomb, un système similaire de chiffrement des données utilisateurs. Malheureusement, cette version se limite aux tablettes tactiles et l'entreprise de Mountain View semble réticente à rendre publics le type de chiffrement pratiqué ainsi que le code source de cette dernière mouture de leur système d'exploitation mobile [HONE].

Au cours de la dernière Google I/O, il a pourtant été annoncé que la prochaine version d'Android censée unifier tablettes et smartphones, nommée Ice Cream Sandwich, inclurait de nombreuses fonctionnalités issues de Honeycomb [IO11]. Au moment où nous rédigeons cet article, rien n'a encore été révélé concernant un éventuel chiffrement des données internes...

Les possibilités sont donc pour l'instant limitées à quelques terminaux et il nous a paru intéressant de mettre en œuvre une modification pouvant être réalisée sur tout type d'appareil Android.

1.2. Pré-requis

La mise en place d'un système de chiffrement avec authentification pre-boot pour Android étant une modification intervenant en profondeur sur le système d'exploitation, certains pré-requis sont nécessaires.

1.2.1. SDK, sources et accès root

La présence du SDK Android est indispensable afin de disposer des outils d'interaction avec le terminal mobile (adb notamment) et si nous optons pour la création d'une version modifiée d'Android, il faudra se procurer les sources nécessaires[AOSP].

Néanmoins, en fonction du matériel utilisé, l'utilisation des sources fournies par l'Android Open Source Project ne sera pas forcément suffisante. Certains composants du firmware sont en effet propriétaires et il sera nécessaire d'extraire au préalable ceux-ci du terminal.

De plus, un accès total au système est nécessaire, il faudra donc disposer d'un terminal débloqué disposant des droits d'accès root.

La solution la plus simple à mettre en place sera de modifier le système déjà existant (au risque de perdre en stabilité du système, voir partie 3 Chiffrement de l'intégralité des données utilisateurs) ou de modifier un firmware non officiel.

Nos tests ont été effectués sur un firmware modifié CyanogenMod 7.0.3 [CYAN] sans problème de stabilité.

1.2.2. Portage de cryptsetup

Afin de chiffrer nos données, nous allons tirer parti du fait que le noyau Android supporte le module dm-crypt[DMC]. Pour cela, il faudra disposer d'un exécutable compilé pour l'architecture des terminaux Android (architecture ARM), fort heureusement quelques acharnés du système d'exploitation mobile se sont déjà donnés la peine de cross-compiler cryptsetup [CRYP].

2. Création d'un conteneur sécurisé

En guise d'introduction, nous allons créer un conteneur chiffré situé sur la carte SD du terminal afin d'y stocker nos données privées.

La manipulation est relativement simple à effectuer, particulièrement pour les utilisateurs réguliers de LUKS sous Linux, et se résume ainsi :

  1. création d'un fichier de la taille souhaitée qui servira de conteneur ;
  2. montage du fichier sur un loopback device ;
  3. création d'un système de fichiers valide ;
  4. chiffrement à l'aide de cryptsetup ;
  5. déchiffrement et montage pour l'utilisation.

2.1. Préparation du conteneur sur la carte SD

En premier lieu, il faut pousser l’exécutable cryptsetup récupéré plus haut (voir partie 1.2.2 Portage de cryptsetup) sur le système Android :

# adb remount

remount succeeded

# adb push cryptsetup /system/bin

[...]

# adb shell

# chmod 755 /system/bin/cryptsetup

Nous créons à présent un fichier de 1Go sur la carte et nous le montons sur un loopback device.

Nous l'avons nommé .tmp. Bien sûr, ce nommage ne trompera pas un attaquant déterminé, mais il est toujours bon de ne pas attirer l'attention et préfixer le nom d'un point dupera les explorateurs de fichiers de mauvaise qualité ou mal configurés.

# dd if=/dev/zero of=/mnt/sdcard/.tmp bs=1024 count=100000

# mknod /dev/loop0 b 7 0

100000+0 records in

100000+0 records out

102400000 bytes transferred in 18.133 secs (5647162 bytes/sec)

# losetup /dev/loop0 /mnt/sdcard/.tmp

Utilisons à présent cryptsetup pour préparer le conteneur :

# cryptsetup luksFormat -c aes-plain /dev/loop0

WARNING!

========

This will overwrite data on /dev/loop0 irrevocably.

Are you sure? (Type uppercase yes): YES

Enter LUKS passphrase: **************

Verify passphrase:

# cryptsetup luksOpen /dev/loop0 vault

Enter passphrase for /dev/loop0: **************

# cryptsetup status vault

/dev/mapper/vault is active.

  type: LUKS1

  cipher: aes-cbc-plain

  keysize: 256 bits

  device: /dev/loop0

  offset: 4096 sectors

  size:    195904 sectors

  mode:    read/write

Le chiffrement est en place, il ne reste plus qu'à créer le système de fichiers :

#mke2fs -O uninit_bg,resize_inode,extent,dir_index -L Vault0 -FF /dev/mapper/vault

mke2fs 1.41.10 (10-Feb-2009)

Filesystem label=Vault0

OS type: Linux

Block size=1024 (log=0)

Fragment size=1024 (log=0)

Stride=0 blocks, Stripe width=0 blocks

[...]

Writing inode tables: done                            

Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 25 mounts or

180 days, whichever comes first. Use tune2fs -c or -i to override.

et à le monter :

# mkdir /mnt/sdcard/vault

# mount /dev/mapper/vault /mnt/sdcard/vault

2.2. Création des scripts d'utilisation

Afin de faciliter l'utilisation de notre conteneur, nous écrivons un jeu de scripts pour l'ouvrir et le fermer.

Voici le script permettant de monter et d'ouvrir le conteneur :

#!/system/bin/sh
mknod /dev/loop0 b 7 0

losetup /dev/loop0 /mnt/sdcard/.tmp

cryptsetup luksOpen /dev/loop0 vault

mount /dev/mapper/vault /mnt/sdcard/vault

ainsi que le script permettant de démonter la partition et fermer le conteneur :

#!/system/bin/sh
umount /mnt/sdcard/vault

cryptsetup luksClose vault

Nous disposons à présent d'un répertoire sur la carte SD activable et désactivable à volonté, où les données déposées sont chiffrées et protégées par un mot de passe.

3. Chiffrement de l'intégralité des données utilisateurs

Android répartit ses données dans quatre partitions :

  • /system : contient les applications système, les bibliothèques, les fichiers de configuration et le framework Android, elle est montée en lecture seule.
  • /cache : stocke le cache des applications Android.
  • /sdcard ou /mnt/sdcard selon les appareils : comme son nom l'indique, c'est le point de montage de la carte micro SD.
  • /data : c'est là que sont stockées les applications installées par l'utilisateur ; y sont également stockés les paramètres et les préférences pour ces applications dans des bases de données SQLite.

C'est cette dernière partition que nous souhaitons chiffrer afin de protéger les données sensibles (applications installées, mots de passe et réglages dans les bases de données, etc.).

La démarche de chiffrement des données utilisateurs demandant la migration de toutes les données de la partition /data dans un conteneur, il est préférable d'appliquer ces modifications au système Android avant de l'installer sur le terminal.

En effet, la copie du contenu de /data pendant l’exécution du système peut poser problème (permissions, fichiers temporaires, liens symboliques, etc.) ; il ne s'agit pas d'une méthode fiable, et au cours de nos tests, certaines applications se sont révélées instables et ont dû être réinstallées pour fonctionner à nouveau normalement.

3.1. Préparation de la partition chiffrée

Disposant d'une partition /data d'environ 210 Mo, nous reprenons donc les manipulations de la partie précédente pour créer un nouveau conteneur. Il est légèrement plus petit que la taille de la partition afin de pouvoir loger sur cette même partition /data, 10 Mo de marge sont plus que suffisants :

# dd if=/dev/zero of=/tmp/data.encrypted bs=1M count=200

# mknod /dev/loop0 b 7 0

# losetup /dev/loop42 /tmp/data.encrypted

# cryptsetup luksFormat -c aes-plain /dev/loop0

# cryptsetup luksOpen /dev/loop42 data

# mke2fs -O uninit_bg,resize_inode,extent,dir_index -L Data0 -FF /dev/mapper/data

# mount /dev/mapper/data /mnt

Nous déposons ensuite le fichier sur /data afin de pouvoir y accéder durant la phase de boot du terminal.

3.2. Modification des scripts de démarrage d'Android

Le processus de démarrage d'Android de résume en deux phases principales :

  1. Le lancement du processus init et l’exécution d'un script init.rc qui se charge de créer l'arborescence du système, de monter les partitions, puis de lancer les différents services.
  2. L'appel par init.rc du processus zygote,une base pour les applications Android qui sont des forks de ce processus.

3.2.1. Écriture d'un programme de déblocage pre-boot

Afin de pouvoir déchiffrer et monter la partition /data avant son utilisation par le processus de démarrage ou par zygote, il est nécessaire de disposer d'un programme pouvant s'insérer au début d'init.rc afin de procéder à l'authentification.

Pour l'exemple, nous avons écrit un programme en C volontairement simpliste donnant le mot de passe à cryptsetup :

int main(int argc, char **argv, char **envp)

{

  char buffer[2048];

  char passphrase[1024] = "ma passphrase";

  bzero(buffer, sizeof(buffer));

  snprintf(buffer, sizeof(buffer) – 1,

 "echo %s | /system/bin/cryptsetup luksOpen /dev/block/loop0 data", passphrase);

  system(buffer);

  return (0);

}

Le binaire devra être compilé pour la plate-forme ARM et de préférence sous forme statique afin de ne dépendre d'aucune bibliothèque qui pourrait ne pas être accessible à cette étape du processus de démarrage.

Évidemment, l'utilisation d'un programme contenant le mot de passe en dur dans le code annule la sécurité apportée par le chiffrement...

Une solution plus pertinente serait l'écriture d'un programme nous permettant de demander un mot de passe à l'utilisateur au tout début de la séquence de démarrage afin de déchiffrer les données contenues sur le smartphone. Cette opération se déroulant avant le chargement complet du système Android (qui dépend des données chiffrées), il faudra donc écrire un programme utilisant par exemple la libminui, habituellement utilisée pour la création de programmes pour la partition de recovery. Cette tâche relativement complexe pourrait faire à elle seule l'objet d'un article.

Certains développeurs de firmwares alternatifs intégrant le chiffrement dans leur version modifiée d'Android ont par ailleurs déjà développé de tels programmes d'authentification, proposant ainsi des systèmes d'authentification allant de la simple entrée texte jusqu'à la génération de mot de passe complexe en utilisant des motifs graphiques [XDA].

menu

Fig. 1 : Exemple de programme d'authentification pre-boot pour Android

Des alternatives telles que la présence de certificats sur support amovible ou l'identification biométrique sont également à envisager sur ces terminaux dont le matériel évolue très rapidement. Il existe par ailleurs des cartes micro SD intégrant une puce RFID, pouvant permettre, par exemple, le démarrage du terminal et le déchiffrement de ses partitions tout en servant de support de données amovible. Certaines solutions de conteneurs chiffrés à authentification biométrique existent [BIO], mais à notre connaissance, aucune solution de ce type n'autorise le déchiffrement avant le chargement du système d'exploitation Android.

3.2.2. Édition de init.rc

Avec notre programme d'authentification sous la main, il nous faut à présent modifier le script de démarrage d'Android.

Durant son démarrage, Android interagit de manière répétée avec la partition data (création de cache, lecture des bases SQLite, etc.). Il nous faut donc intervenir le plus tôt possible dans le processus de démarrage.

Il faut identifier les lignes qui correspondent au montage des partitions et y insérer nos instructions :

[...]
on fs
# mount mtd partitions
# Mount /system rw first to give the filesystem a chance to save a checkpoint
mount yaffs2 mtd@system /system
mount yaffs2 mtd@system /system ro remount
# création d'un point de montage pour la partition data (qui ne contient plus qu'un fichier chiffré)
 mkdir /encrypted-data 0771 system system
 mount yaffs2 mtd@userdata /encrypted-data nosuid nodev
# mount yaffs2 mtd@userdata /data nosuid nodev
mount yaffs2 mtd@cache /cache nosuid nodev
# montage du fichier chiffré sur un loopback device
exec /system/bin/losetup /dev/block/loop0 /encrypted-data/data.encrypted
# lancement de notre programme d'authentification
exec /system/bin/unlock
# montage de notre partition déchiffrée sur /data
mount ext2 /dev/mapper/data /data
[...]

Pour les manipulations décrites ici, tous les programmes utilisés ont été placés dans /system/bin/ avec les permissions d’exécution.

Bien que les manipulations décrites ici s'inscrivent dans le cadre de la création d'une version modifiée d'Android, il peut également être intéressant d'appliquer ce chiffrement sur un système déjà existant, auquel cas modifier le script init.rc peut se révéler plus difficile.

En effet, la partition /system contenant l'arborescence de base d'Android est un ramdisk accessible uniquement en lecture seule, il faut donc l'extraire du système pour le modifier.

Première étape, identifier la partition boot :

# cat /proc/mtd | grep boot

mtd0: 00300000 00020000 "boot"

Nous pouvons ensuite effectuer un dump de la partition sur la carte SD :

# cat /dev/mtd/mtd0 > /mnt/sdcard/boot.img

# exit

# adb pull /mnt/sdcard/boot.img

Nous récupérons donc une image contenant un en-tête de 2Ko, le kernel (compressé avec gzip) et le ramdisk. La méthode la plus simple pour manipuler cette image est d'utiliser deux scripts Perl (unpack-bootimg.pl et repack-bootimg.pl) dont l'utilisation est largement répandue parmi les développeurs de firmwares alternatifs [BOOT].

Le premier se charge simplement de supprimer l’en-tête puis d'extraire le kernel et le ramdisk :

# ,/unpack-bootimg.pl boot.img

kernel written to boot.img-kernel.gz

ramdisk written to boot.img-ramdisk.cpio.gz

gzip: ../boot.img-ramdisk.cpio.gz: decompression OK, trailing garbage ignored

713 blocks

extracted ramdisk contents to directory boot.img-ramdisk/

# ls -l

total 6148

-rw-r--r-- 1 root root 3145728 2011-05-20 07:38 boot.img

-rw-r--r-- 1 root root 2168832 2011-05-20 07:39 boot.img-kernel.gz

drwxr-xr-x 8 root root    4096 2011-05-20 07:39 boot.img-ramdisk

-rw-r--r-- 1 root root 974848 2011-05-20 07:39 boot.img-ramdisk.cpio.gz

Nous retrouvons dans boot.img-ramdisk l'arborescence de base du système et le fichier init.rc.

Une fois les modifications apportées à init.rc, nous pouvons rassembler le tout avec le script repack-bootimg.pl :

# ./repack-bootimg.pl boot.img-kernel.gz boot.img-ramdisk new-boot.img

[...]

repacked boot image written at boot.img-ramdisk-repack.img

Il ne reste plus qu'à écraser l'ancienne partition boot du terminal avec notre nouvelle image :

# adb push new-boot.img /sdcard/

# adb shell

# flash_image boot /sdcard/new-boot.img

# reboot

Conclusion

Nous disposons donc à présent d'un conteneur chiffré qu'il est possible d'étendre à toute la carte SD. Avec quelques manipulations supplémentaires, un chiffrement complet de toutes les données contenues sur la partition userdata(/data) est également possible, nous permettant ainsi de protéger l'intégralité des données utilisateurs contre les attaques off-line.

L'utilisation du terminal et des applications stockées sur cette partition chiffrée ne semble pas être impactée en termes de performances. Nous n'avons noté aucun ralentissement ou dysfonctionnement majeur de l'environnement Android et nous n'avons pas perçu d’éventuelle perte d'autonomie de la batterie.

On peut toutefois noter que le niveau de sécurité dépendra du système d'authentification utilisé et l'emploi d'un mot de passe fort est recommandé (plus de 14 caractères, avec majuscules, chiffres et caractères spéciaux).

La partition /boot ne pouvant être chiffrée de la manière décrite ici, une personne ayant un accès physique au terminal pourra en effet assez rapidement analyser le fonctionnement du système déployé et tenter de décompiler le programme d'authentification pre-boot pour analyser son fonctionnement.

Les données étant stockées sous forme de fichier conteneur, l'extraction de celui-ci afin de tenter un cassage hors-ligne est possible. De plus, comme quasiment tous les systèmes de chiffrement de disques, LUKS garde en RAM la passphrase et est donc vulnérable à des attaques de type cold-boot.

D'une manière générale, il s'agit plus d'une forme de dissuasion, puisqu'à partir du moment où il obtient un accès physique au terminal, il est fort probable qu'un attaquant déterminé parvienne à en extraire des données. Ce n'est qu'une question de temps et de moyens.

Références

[APP] http://images.apple.com/iphone/business/docs/iPhone_Security.

[BLACK] http://docs.blackberry.com/en/admin/deliverables/7325/How_BESolution_uses_TDES_to_encrypt_data_834425_11.jsp

[IPHO] http://www.sit.fraunhofer.de/forschungsbereiche/projekte/Lost_iPhone.jsp

[WHS] http://www.whispersys.com/whispercore.html

[HONE] http://www.engadget.com/2011/02/02/android-3-0-honeycomb-can-encrypt-all-your-data-needs-a-full/

[IO11] http://www.talkandroid.com/40365-chief-announcements-from-google-io-keynote-ice-cream-sandwich-updates-to-honeycomb-usb-host-support-movie-rentals-music-and-a-commitment-to-updates/

[AOSP] http://source.android.com/

[CYAN] http://www.cyanogenmod.com/

[DMC] http://www.saout.de/misc/dm-crypt/

[CRYP] https://androidvoid.wordpress.com/2009/09/30/android-encryption-using-cryptsetup-and-luks/

[XDA] http://forum.xda-developers.com/showthread.php?t=881850

[BIO] http://www.mobbeel.com/products/biowallet/overview/

[BOOT] http://android-dls.com/wiki/index.php?title=HOWTO:_Unpack,_Edit,_and_Re-Pack_Boot_Images



Article rédigé par

Par le(s) même(s) auteur(s)

Présentation de l'OWASP Mobile Security Testing Guide

Magazine
Marque
MISC
Numéro
106
Mois de parution
novembre 2019
Spécialité(s)
Résumé

Paru en juin 2018, l'OWASP Mobile Security Testing Guide (MSTG) est devenu une référence pour appréhender et auditer la sécurité des applications mobiles (Android et iOS). Dans cet article, nous allons passer en revue le guide et présenter quelques exemples d'utilisation.

Retour sur les faiblesses de l’authentification Windows

Magazine
Marque
MISC
Numéro
103
Mois de parution
mai 2019
Spécialité(s)
Résumé

Nous faisions dans MISC n°68 un état des lieux des traces d’authentification laissées par les protocoles d’administration les plus répandus en environnement Windows. Celles-ci restent un « must », récupéré et réutilisé par les attaquants et les pentesters afin de rebondir et d’élever ses privilèges sur les réseaux. Faisons le point 5 ans après.

Les derniers articles Premiums

Les derniers articles Premium

Quarkus : applications Java pour conteneurs

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Initié par Red Hat, il y a quelques années le projet Quarkus a pris son envol et en est désormais à sa troisième version majeure. Il propose un cadre d’exécution pour une application de Java radicalement différente, où son exécution ultra optimisée en fait un parfait candidat pour le déploiement sur des conteneurs tels que ceux de Docker ou Podman. Quarkus va même encore plus loin, en permettant de transformer l’application Java en un exécutable natif ! Voici une rapide introduction, par la pratique, à cet incroyable framework, qui nous offrira l’opportunité d’illustrer également sa facilité de prise en main.

De la scytale au bit quantique : l’avenir de la cryptographie

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Imaginez un monde où nos données seraient aussi insaisissables que le célèbre chat de Schrödinger : à la fois sécurisées et non sécurisées jusqu'à ce qu'un cryptographe quantique décide d’y jeter un œil. Cet article nous emmène dans les méandres de la cryptographie quantique, où la physique quantique n'est pas seulement une affaire de laboratoires, mais la clé d'un futur numérique très sécurisé. Entre principes quantiques mystérieux, défis techniques, et applications pratiques, nous allons découvrir comment cette technologie s'apprête à encoder nos données dans une dimension où même les meilleurs cryptographes n’y pourraient rien faire.

Les nouvelles menaces liées à l’intelligence artificielle

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Sommes-nous proches de la singularité technologique ? Peu probable. Même si l’intelligence artificielle a fait un bond ces dernières années (elle est étudiée depuis des dizaines d’années), nous sommes loin d’en perdre le contrôle. Et pourtant, une partie de l’utilisation de l’intelligence artificielle échappe aux analystes. Eh oui ! Comme tout système, elle est utilisée par des acteurs malveillants essayant d’en tirer profit pécuniairement. Cet article met en exergue quelques-unes des applications de l’intelligence artificielle par des acteurs malveillants et décrit succinctement comment parer à leurs attaques.

Les listes de lecture

9 article(s) - ajoutée le 01/07/2020
Vous désirez apprendre le langage Python, mais ne savez pas trop par où commencer ? Cette liste de lecture vous permettra de faire vos premiers pas en découvrant l'écosystème de Python et en écrivant de petits scripts.
11 article(s) - ajoutée le 01/07/2020
La base de tout programme effectuant une tâche un tant soit peu complexe est un algorithme, une méthode permettant de manipuler des données pour obtenir un résultat attendu. Dans cette liste, vous pourrez découvrir quelques spécimens d'algorithmes.
10 article(s) - ajoutée le 01/07/2020
À quoi bon se targuer de posséder des pétaoctets de données si l'on est incapable d'analyser ces dernières ? Cette liste vous aidera à "faire parler" vos données.
Voir les 130 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous