Architecture du système Android
Noyau Android
Le noyau Android est une version modifiée du noyau Linux et représente le cœur du système. Le noyau est le programme servant d’interface entre les différents composants du système (périphériques, processus, fichiers etc). Parmi les modifications notables apportées dans le noyau Android, nous pouvons citer les mécanismes binder, ashmem, wakelock, low memory killer, logger, RAM console et Paranoid Networking.
Binder est un mécanisme de communication entre processus et d’appel de méthodes distantes. L’appel de méthodes distantes, appelé Remote Procedure Call en anglais, consiste à faire exécuter une méthode par une entité distante. Il est inspiré du projet OpenBinder [81]. Comme nous le verrons par la suite, il est un élément essentiel du fonctionnement du système Android. Ashmem pour Anonymous Shared Memory est un mécanisme de partage de mémoire similaire à celui du noyau Linux shm. Il est utilisé pour partager les données entre applications Android. Parmi les ”nouveautés” apportées par ashmem il y a par exemple l’usage de compteur pour connaître le nombre de processus faisant référence à une zone de mémoire partagée et éviter les fuites de mémoire. Wakelock est un mécanisme servant à notifier le noyau de ne pas se mettre en veille. Contrairement aux systèmes Linux, le système Android essaie par défaut de se mettre en veille étant donné qu’il est destiné à tourner sur des appareils à ressources limitées. Lors d’exécution de code ne devant être interrompu, le wakelock est ainsi utilisé pour dire au système de rester éveillé. Low memory killer est un mécanisme utilisé par le noyau pour libérer de la mémoire lorsqu’il ne reste plus assez de mémoire. Logger est un mécanisme de journalisation qui écrit les évènements du système uniquement dans des zones allouées en mémoire. Contrairement aux systèmes Linux traditionnels, les évènements écrits dans le journal du système ne sont ainsi jamais écrits dans un fichier. RAM Console est un mécanisme qui préserve en mémoire le contenu des évènements systèmes ajoutés par du code noyau (via la fonction printk) lors de la précédente exécution du système. Son contenu est accessible via le fichier /proc/last_kmsg. Sous Linux, le contenu du journal des évènements systèmes sont stockés de manière persistante dans les fichiers sous le répertoire /var/log/. Ce n’est pas le cas sous Android et en cas de crash du système par exemple, il devient impossible de récupérer les évènements qui ont amené au crash. RAM Console est ainsi été créé pour résoudre cette limitation du système de journalisation sous Android.
Paranoid Network est un mécanisme contrôlant l’accès des applications au réseau. Sous Linux, toute application a le droit d’utiliser les sockets et accéder au réseau. La socket est la structure de base liée aux opérations réseaux sous Linux. Sous Android, l’inverse est la règle car seule les applications avec une autorisation explicite sont autorisées à créer des sockets et communiquer sur le réseau.
Espace utilisateur
La couche Applications renferme les applications fournies par défaut sur le téléphone ainsi que celles qui seront installées plus tard par l’utilisateur. Il s’agit des applications avec lesquelles l’utilisateur pourra interagir en général (ex : application de messagerie et gestion des contacts). Les applications Android sont principalement écrites en Java. Android donne cependant la possibilité d’écrire du code natif et de l’appeler au sein de l’application grâce à une interface appelée Java Native Interface dont le rôle est d’interfacer du code Java avec du code natif écrit en C. Android framework est l’ensemble des services et ressources fournies par le système Android. Il s’agit principalement de services tournant dans quelques processus clés du système Android tels que system_server et mediaserver. La commande service list retourne sous Android la liste des services présents dans le système. Sous Android 2.3, la commande retourne une liste de 50 services et sous Android 4.2 68 services. Parmi ces services nous pouvons citer ServiceManager, LocationManager. ServiceManager recense tous les autres services tournant sur le téléphone et joue un rôle d’annuaire pour les applications souhaitant accéder à un service en particulier sur le téléphone. Lorsqu’une application de navigation souhaite par exemple connaître la localisation de l’utilisateur, elle va dans un premier temps demander au Service-Manager la référence de Location Service. Une fois cette référence récupérée, elle pourra demander à Location Service les données de géolocalisation. Surfaceflinger est un autre service avec un rôle crucial sous Android. C’est lui qui est chargé de composer et dessiner ce que les différentes applications souhaitent afficher à l’écran de l’appareil.
Android runtime est l’environnement d’exécution des applications Android. Il contient la bibliothèque Java utilisable par les applications ainsi qu’une machine virtuelle appelée Dalvik. La bibliothèque reprend une partie de la bibliothèque Java standard plus quelques bibliothèques supplémentaires propres à Android. La machine virtuelle Dalvik elle interprète le bytecode dans lequel les applications Android ont été compilées. Le bytecode dalvik est différent du bytecode Java d’où l’usage de Dalvik à la place des machines virtuelles Java standard. Depuis Android 4.4, une deuxième machine virtuelle, ART [85, 99], qui est livrée sous forme expérimentale avec la plateforme. Libraries renferme les bibliothèques natives du système. Elles sont généralement utilisées par les applications natives du système. Parmi les bibliothèques nous pouvons par exemple citer bionic qui renferme entre autres une bibliothèque C et une bibliothèque pour le support du C++. Selon la page Wikipédia sur bionic [3], il s’agit d’une version modifiée de la bibliothèque standard C de BSD et est propre à Android. Si les applications utilisateurs sont des applications écrites en Java, il existe tout de même quelques applications natives dans le système. Il s’agit de services propres au système et de quelques outils en ligne de commande qui peuvent s’avérer utiles pour un développeur. Ces applications n’ont pas pour but d’être utilisées par l’utilisateur lambda. HAL ou Hardware Abstraction Layer sert d’interface standard entre le système et les pilotes des périphériques présents sur l’appareil (ex : caméra, capteur etc). Les constructeurs écrivent ainsi les pilotes à leur guise mais doivent fournir les méthodes correspondant aux interfaces HAL pour que le système puisse utiliser les périphériques.
Communications entre processus
Android est un environnement d’exécution où les applications sont poussées à collaborer pour fonctionner. Le but de cette collaboration est de limiter la duplication de code dans les applications et de proposer un ensemble assez grand de fonctionnalités aux différentes applications du système. Un exemple illustrant cette collaboration est l’application caméra. Pour utiliser la caméra d’un appareil, une application doit connaître son mode de fonctionnement exact sachant qu’une caméra peut être différente d’un modèle de téléphone à un autre. Pour faciliter la tâche au développeur de l’application, l’application caméra du téléphone propose une interface permettant aux autres applications de prendre des photos ou enregistrer des vidéos à leur place puis leur transmettre le résultat. Ce système de collaboration repose plusieurs fonctionnalités du système. Du point de vue des développeurs d’application, la collaboration repose sur l’usage des intents et des composants Content Provider pour échanger des messages et partager du contenu . À un niveau plus bas, la collaboration repose sur deux fonctionnalités d’Android que sont Binder et Ashmem. ces deux mécanismes servent à effectuer des appels distants de procédure et partager des zones de mémoire entre processus.
Applications Android
Architecture d’une application : les différents composants
Une application Android est écrite en Java. Contrairement aux applications Java standard, une application Android peut posséder plusieurs points d’entrée. Plus précisément, une application Android peut avoir plusieurs composants et chacun d’eux peut-être un point d’entrée dans le programme. Il existe quatre types de composants : Activity, ContentProvider, Service et BroadcastReceiver.
Activity Un composant Activity est une interface utilisateur. Une application de messagerie électronique peut par exemple avoir trois composants Activity : un pour naviguer entre les répertoires de la messagerie, le deuxième pour l’affiche d’un message et le dernier pour l’édition et l’envoi.
ContentProvider Un ContentProvider est un composant servant au partage de données d’une application. Son rôle est de servir d’interface entre l’application souhaitant accéder aux données et les données. Ces données sont généralement stockées dans une base de données locale SQLite mais aucune restriction n’est imposée sur la manière de stocker les données. La liste des contacts est par exemple stockée dans une base de données locales dont l’accès se fait à travers un composant de type ContentProvider.
Service Un service est un composant effectuant des tâches en arrière plan. Il est utilisé pour effectuer de longue tâches internes à l’application ou à exécuter une tâche à la demande d’une application. Dans un client File Transfer Protocol, un service est utilisé pour envoyer les données sur le réseau à les recevoir. Cela évite de bloquer l’application jusqu’à la fin de l’envoi.
BroadcastReceiver Un BroadcastReceiver est un composant utilisé pour écouter les messages en large diffusion sur le système. Un exemple de ce type de message est la réception d’un nouveau SMS. Lorsqu’un nouveau SMS est reçu par le téléphone, le système envoie un message en broadcast pour notifier les différentes applications d’envoi et réception de SMS. Ce composant ne possède aucune interface graphique et n’est pas censé exécuter de longues tâches.
|
Table des matières
1 Introduction
2 État de l’art
2.1 Système Android
2.1.1 Architecture du système Android
2.1.2 Applications Android
2.2 Sécurité du système Android
2.2.1 Mécanismes issus de Linux
2.2.2 Mécanismes propres à Android
2.3 Limites des mécanismes de sécurité Android
2.3.1 Abus de permission
2.3.2 Permissions : attaques par délégation et attaques par collusion
2.3.3 Communication entre composants via les intents
2.3.4 Failles logicielles : élévation de privilège
2.4 Malware Android
2.4.1 Définitions
2.4.2 Malwares Android : 2010 à 2011
2.4.3 Malwares Android en 2013
2.5 Renforcement de la sécurité sous Android
2.5.1 Protection des ressources sensibles
2.5.2 Communication entre processus et entre composants
2.5.3 Abus des permissions
2.6 Suivi de flux d’information
2.6.1 Suivi de flux au sein d’une application
2.6.2 Suivi de flux au niveau système
2.6.3 Suivi de flux au niveau hardware
2.7 Classification et détection de malware
2.8 Analyse d’applications Android
2.8.1 Désassembleur, décompilateur
2.8.2 Comparaison d’applications
3 Blare : un moniteur de flux d’information
3.1 Modèle théorique
3.1.1 Conteneurs d’information
3.1.2 Information et contenu courant d’un objet : itag
3.1.3 Politique de flux d’information : pxqptag
3.1.4 Suivi et contrôle de flux d’information
3.2 Définition d’une politique de flux d’information
3.3 KBlare : suivi et contrôle de flux via LSM
3.4 AndroBlare : Blare sous Android
3.4.1 Communication entre processus : Binder
3.4.2 Suivi de flux d’information dans le Binder
3.4.3 Exécution des applications Android
3.4.4 Description des flux observés
3.4.5 Outils en espace utilisateur
3.5 AndroBlare : analyse d’applications Android
4 Graphes de flux système
4.1 Graphe de flux système
4.2 Quelques opérations utiles sur les SFG
4.2.1 Intersection de deux SFG : g1 g2
4.2.2 Inclusion d’un SFG dans un autre : g1 g2
4.2.3 Nœuds et arcs d’un SFG
4.3 Construction d’un graphe de flux système
4.4 SFG : profil comportemental d’une application
4.4.1 Analyse de DroidKungFu1 avec AndroBlare
4.4.2 Analyse du SFG de DroidKungFu1
4.5 Politique de flux d’information à partir d’un SFG
5 Caractérisation et détection de malware
5.1 Caractérisation de malware Android
5.2 Évaluation de la méthode de classification
5.2.1 Jeu de donnée
5.2.2 Expérimentation et résultat
5.3 De la nécessité du filtrage
5.4 Détection d’exécution de malware Android
5.5 Évaluation de la capacité de détection
6 Conclusion
A Évènements déclencheurs de code malveillant
A.1 Outils
A.2 BadNews
A.3 DroidKungFu1
A.4 DroidKungFu2
A.5 jSMSHider
Publications