• Aucun résultat trouvé

Interfaces de programmation applicatives

Les interfaces de programmation applicatives du WiFi permettent d’accéder à certaines données comme par exemple l’adresse MAC de l’interface WiFi qui représente dans notre contexte un identifiant unique. Cette sous-section étudiera trois cas : la faisabilité de la collecte de cet identifiant au travers de l’utilisation des interfaces de programmation proposées, la possibilité ou non de sonder les canaux WiFi pour détecter la présence de périphériques à portée et de collecter leur identifiant et les méthodes à utiliser pour récupérer la position géographique du smartphone. Chaque cas sera analysé selon le système d’exploitation d’Android et d’iOS.

7.4.1 Android

L’utilisation de la classe WifiManager fournit par l’interface de programmation permet de gérer différents aspects d’une connectivité avec le WiFi.

7.4.1.1 Obtention de l’adresse MAC WiFi du smartphone

Premièrement, il est possible de récupérer l’adresse MAC WiFi comme suit :

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE); WifiInfo info = manager.getConnectionInfo();

String address = info.getMacAddress();

Cette version du code fonctionne avec toutes les versions d’Android antérieur à la version 6.0. A partir de cette dernière, la méthode d’accès à l’adresse MAC a été retirée par Android pour apporter plus de sécurité sur ces informations liées à la vie privée des utilisateurs. La valeur de l’adresse MAC par défaut renvoyée est 02 :00 :00 :00 :00 :00.

Cependant, une alternative existe pour accéder à cette valeur en utilisant des combinai-sons d’autres interfaces de programmation publiques proposées. L’idée derrière ce code est de lister toutes les interfaces réseaux liées au smartphone et de trouver celle qui correspond au WiFi (dans cet exemple, wlan0 a été utilisé) :

public String getMacAddr() { try {

// Lister toutes les interfaces reseaux List<NetworkInterface> all =

Collections.list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface nif : all) {

// Si le WiFi exite,

if (!nif.getName().equalsIgnoreCase("wlan0")) continue;

// On recupere la valeur de l’adresse MAC reelle en bytes byte[] macBytes = nif.getHardwareAddress();

// Si elle n’existe pas, on quitte la methode if (macBytes == null) {

return ""; }

Annexes : Outils pour le WiFi 120

// Sinon, on convertit cette valeur en chaine de caracteres StringBuilder res = new StringBuilder();

for (byte b : macBytes) {

res.append(Integer.toHexString(b & 0xFF) + ":"); }

if (res.length() > 0) {

res.deleteCharAt(res1.length() - 1); }

// Et, on retourne le resultat return res.toString();

}

} catch (Exception ex) { }

//Sinon, on renvoit la valeur par defaut return "02:00:00:00:00:00";

}

7.4.1.2 Obtention de l’adress MAC de point d’accès à portée

Une fonctionnalité intéressante serait de pouvoir sonder les canaux WiFi et de lister les AP à portée identifiés par leur adresse MAC. Il est possible de le faire grâce au code suivant :

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

// On lance le scan manager.startScan();

// On recupere les resultats results = wifi.getScanResults();

// Pour chaque point d’accès a portée, on affiche l’adresse MAC et le nom du reseau for (ScanResult result : results) {

Log.v("Test", "Address : "+result.BSSID+" and SSID : "+result.SSID); }

Les récentes mise à jour des versions d’Android requièrent désormais deux permissions supplémentaires pour accéder à ces valeurs : les permissions ACCESS_COARSE_LOCATION et/ou ACCESS_FINE_LOCATION. En effet, le résultat des scan WiFi peut être ex-ploité par des services WPS (WiFi Positionning System, qui par trilateration des points d’accès, permettent d’avoir de localiser le smartphone de manière plus précise que le GPS dans un environnement urbain. Ainsi toute application ayant accès aux scans WiFi peut avoir accès à la position de l’utilisateur. Il était donc devenu nécessaire de contrôler l’accès à ces informations et d’avertir l’utilisateur sur les conséquences de l’autorisation ACCESS_WIFI_STATE.

Google fourni un service de WPS. L’exemple ci-dessous permet d’obtenir la position du smartphone via WPS, sans avoir recours au capteur GPS. Les seules interfaces utilisées seront le WiFi et le réseau cellulaire.

// Recuperer une instance d’un objet permettant d’interagir avec la position et les mouvements du \textit{smartphone} LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

// Lancement du processus de mise a jour periodique de la position String locationProvider = LocationManager.NETWORK_PROVIDER;

locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);

// Recuperer la derniere position connue

Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);

7.4.2 iOS

Depuis la version d’iOS 7.0, les interfaces de programmation du WiFi ne possèdent plus de méthode permettant de récupérer l’adresse MAC WiFi réelle du smartphone pour des raisons évidentes de sécurité. Même si les développeurs utilisent les méthodes existantes, une valeur par défaut (02 :00 :00 :00 :00 :00) sera toujours renvoyée.

Pour pallier ce problème, Apple a mis en place l’utilisation d’un UUID (Universally Unique Identifier, RFC4122), un identifiant codé sur une séquence de 128 bits qui peut garantir l’unicité selon l’espace et le temps. Cependant, pour une sécurité toujours plus forte, Apple rejette toute application de son store qui utilise cette valeur. Le système a ainsi définie deux types d’UUID mise à disposition des développeurs : l’identifiant vendeur (a.k.a. vendor ) et l’identifiant publicitaire.

Annexes : Outils pour le WiFi 122

7.4.2.1 Identifiant vendeur - Vendor specific UUID

La valeur de l’identifiant vendeur est la même pour les applications provenant du même fournisseur et qui s’exécute sur un même smartphone. Une valeur différente sera renvoyée pour toutes les applications sur le même smartphone provenant de différents vendeurs et pour les applications sur différents smartphones quel que soit le fournisseur. Enfin, cette valeur change lorsque l’utilisateur supprime toutes les applications de ce fournisseur de l’appareil et réinstalle ensuite une ou plusieurs d’entre elles.

Les développeurs d’applications ont donc la possibilité d’identifier les smartphone de manière unique, même à travers d’autres applications réalisées par un même développeur. Des applications issues de vendeurs différents percevront cependant des UUID différents pour un même smartphone iOS.

Le code pour récupérer cet identifiant est présenté comme suit :

// Recuperer la valeur de l’identifiant vendeur

UIDevice.currentDevice().identifierForVendor!.UUIDString

De plus, il est aussi possible de récupérer d’autres informations qui peuvent être inférer afin d’avoir des données plus précises sur un utilisateur dans un contexte de suivi de mobilité, comme par exemple le nom associé au smartphone (Ex : iPhone de Taher ), le modèle ou encore le nom et la version du système d’exploitation utilisé :

// Nom associe au smartphone UIDevice.currentDevice().name

// Modele du smartphone

UIDevice.currentDevice().model

// Nom du systeme d’exploitation UIDevice.currentDevice().systemName

// Version du systeme d’exploitation UIDevice.currentDevice().systemVersion

7.4.2.2 Identifiant publicitaire

Cependant, pour les réseaux publicitaires, qui nécessitent un identifiant cohérent et qui ne change pas entre les applications de différents développeurs, une approche différente est requise : l’utilisation d’un identifiant publicitaire.

Depuis iOS 6.0, Apple a introduit l’identifiant publicitaire, un identifiant du smartphone non personnel et non permanent, que les réseaux publicitaires utilisent pour donner à l’utilisateur plus de contrôle sur la capacité des annonceurs à fournir des publicités ciblés grâce à leur méthode de suivi de mobilité. L’utilisateur peut donc choisir à tous moment de change la valeur de l’identifiant ou de limiter les informations envoyées (sa position par exemple).

Le code suivant montre comment une application peut obtenir cet identifiant :

Si un identifier publicitaire est utilise, alors on l’affiche if ASIdentifierManager.sharedManager().advertisingTrackingEnabled{

myAdvId=ASIdentifierManager.sharedManager().advertisingIdentifier.UUIDString Log.d("TEST", "Adversiting identifier : "+myAdvId);

}

7.4.2.3 Scans WiFi avec iOS

Nous allons maintenant nous intéresser à la possibilité de sonder les canaux WiFi avec les interfaces de programmation d’iOS. Le système d’Apple bloque les méthodes permettant de scanner les périphériques à portée pour des raisons de sécurité. Il est néanmoins possibilite d’utiliser des interfaces de programmations privées, c’est-à-dire des libraires de codes qui ne sont disponibles qu’en ayant les privilèges super-utilisateur du smartphone. Pour rappel, les applications utilisant des librairies privées ne peuvent pas être déployer sur l’App store et necessitent que les périphériques soient rootés.

De plus, depuis la version 7.0 du système d’exploitation, Apple propose une application utilitaire officielle déployée sur l’App store nommé AirPort Utility permettant aux uti-lisateurs qui la téléchargent d’exécuter des scans de périphériques WiFi à portée. Le temps des scans peut être ajusté et les informations des points d’accès observés que l’on peut obtenir sont l’adresse MAC (BSSID) et le nom du réseau (SSID). Pour le moment, le code source de cet utilitaire n’est pas dévoilé.

Annexes : Outils pour le Bluetooth Classic 124

Enfin, pour accéder aux positions géographique du smartphone, l’interface de program-mation à utiliser est CoreLocation. Ce dernier va utiliser tout le matériel embarqué dis-ponible, y compris le WiFi, le GPS, le Bluetooth, le magnétomètre, le baromètre et le réseau cellulaire pour recueillir des données.

Pour utiliser cette interface, il faudra indiquer la permission dans le fichier info.plist en ajoutant NSLocationAlwaysUsageDescription et un message d’alerte qui sera affiché à l’utilisateur pour lui demander son autorisation afin d’accéder aux données relatives à la position géographique.

Le code suivant présente les étapes à suivre :

// Initialiser l’objet LocationManager locationManager = CLLocationManager() locationManager.delegate = self; // Precision accrue locationManager.desiredAccuracy = kCLLocationAccuracyBest // Demande de l’autorisation locationManager.requestAlwaysAuthorization()

// Mise a jour de la position geographique periodiquement locationManager.startUpdatingLocation()

Pour afficher la position actuelle (longitude et latitude) de l’utilisateur, la méthode sui-vante est utilisée :

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let locValue:CLLocationCoordinate2D = manager.location!.coordinate

print("locations = \(locValue.latitude) \(locValue.longitude)") }

Ce chapitre présente les deux principaux outils utilisés dans le cadre de cette thèse afin d’analyser les paquets émis par les interfaces classic Bluetooth de différents périphériques. D’une part, nous présenterons l’analyseur Ubertooth et d’autre part, nous étudierons l’utilisation des interfaces de programmation applicatives sous iOs et Android en lien avec le Bluetooth.

L’outil Ubertooth est un analyseur de paquets Bluetooth open source destinée aux ex-périmentations sur le protocole Bluetooth Classic/BLE. L’outil permet d’envoyer et de recevoir des paquets sur la bande ISM des 2,4 GHz. Sa puissance maximale théorique est de 20 dBM et à une portée théorique de 100 mètres sans obstacles. La partie logicielle d’Ubertooth est composée de plusieurs librairies à installer. Elles sont compatibles avec un système d’exploitation Linux ou MacOSX et l’Ubertooth peut donc être utilisé sur les nano-ordinateurs tels que le raspberry-pi.