Analyse de Pokemon GO ! (Part 2 : Analyse Réseau)

Dans la première partie de l’analyse de l’application « Pokemon Go », nous avons vu les composants du fichier d’installation, et nous avons décompilé le projet afin de comprendre les dépendances de l’application. Ceci nous a renseigné sur beaucoup de choses. Afin d’avancer dans l’analyse, il faudra regarder ce que fait l’application sur le réseau. C’est l’objectif de cette seconde et dernière partie.

Pk le bluetooth ?

Lors de l’analyse du code décompilé, je me suis rendu compte que la majorité du code du jeu réside à l’interieur du framework unity. Unity est utilisée par les créateurs de jeux vidéo pour créer des jeux qui soit potentiellement executable sur plusieurs plateformes (web, ios, android, …). Ce qui veut dire que ce qui reste du code Android sont les choses impossible à faire via Unity.
Un grand nombre de classes interagissent avec les capacités bluetooth de l’appareil et notamment à l’interieur du  package com.nianticproject.holoholo.sfida.
Une recherche internet m’a permis de voir cet appareil qui fait partie du merchandising Nintendo (voir photo à coté). Il s’agit d’un petit appareil IoT qui permet notemment d’alerter l’utilisateur sur l’existance de pokemon à coté, sans avoir à sortir constamment son téléphone. Ce business fait partie des choses sur lesquelles mise nintendo pour monétiser l’application et le monde des pokemon GO.

Voici une liste de méthodes vue dans le code qui décrivent les interaction avec l’appareil Go plus :

boolean notifyCancelDowser();
boolean notifyError();
boolean notifyFoundDowser();
boolean notifyNoPokeball();
boolean notifyPokeballShakeAndBroken(String str);
boolean notifyPokemonCaught();
boolean notifyProximityDowser(String str);
boolean notifyReachedPokestop(String str);
boolean notifyReadyForThrowPokeball(String str);
boolean notifyRewardItems(String str);
boolean notifySpawnedLegendaryPokemon(String str);
boolean notifySpawnedPokemon(String str);
boolean notifySpawnedUncaughtPokemon(String str);
boolean notifyStartDowser();

Très interessant ! on sait maintenant quel type de notifications sont envoyé depuis l’application vers le Pokemon Go Plus. Si vous vous sentez l’ame d’un maker potentiel ! il serait possible de créer votre propre appareil ! moins cher biensûr que les $34.99 USD de Nintendo 🙂
Pour information, l’appareil sera officiellement disponible à la vente à partir du 31 Juillet. Mais on sait déjà ce qu’il peut faire !
Bonus  : Dump des séquences bluetooth des notifications

Analyse sommaire du flux

Nous y sommes. Pour les initiés d’entre vous, on sait que Pokemon Go communique avec internet ! Notemment pour avoir les positions des Pokemons à afficher sur la carte à l’itnerieur du jeu, mais aussi pour mettre à jour le profil du joueur avec les pokemons capturés, la position GPS … etc.
Ma première tentative était de capturer le flux « brut » de communication de l’application avec internet. Pour faire celà, je vous conseille l’excellente application « Shark for root » disponible sur l’app store. Seule complication : il faut absolument que votre téléphone soit rooté pour que l’application puisse « sniffer » le flux réseau et le capturer sous format .CAP lisible sur PC avec le logiciel Wireshark par exemple, ou tout autre analyseur de protocole compatible format/librairie PCAP.
J’ai donc capturé une session sur Pokemon GO (fichier pcap filtré disponible ici : )
Une première analyse en filtrant les requête « DNS » m’oriente vers le serveur : pgorelease.nianticlabs.com qui est résolu vers l’adresse : 130.211.14.80
Je filtre ensuite sur l’adresse IP et je vois des échanges (comme prévu) crypté en TLS (HTTPS/SSL) avec un flux illisible (voir capture).
capture_trace

Décryptage du traffic

Internet moderne est très sécurisé, l’ensemble du traffic est crypté, il est même impossible en effectuant une capture locale (faite dans le paragraphe précédent) de décrypter le flux, à moins de disposer de la clé privée de la transaction SSL.
Cependant, et puisque nous disposons du téléphone dont le flux est à décrypter, une technique de hacking existe de type du « man in the middle attack« .
En gros, nous allons nous mettre entre le téléphone et internet. Pour celà nous avons besoin de créer un Proxy HTTPS. Son rôle sera, à la récéption d’une requete de l’application, la décrypter en utilisant la clé coté application, la crypter avec la clé coté serveur, attendre une réponse du serveur, la décrypter avec la clé coté serveur, la crypter avec la clé coté application, et l’envoyer vers le téléphone.
Afin que le proxy puisse être utilisé par notre téléphone de test, nous allons forger un certificat et l’installer au niveau du téléphone. Ceci permettera au téléphone de faire confiance à notre serveur domestique et l’utiliser comme proxy HTTPS. Les outils pour faire celà : https://mitmproxy.org/ (gratuit), ou https://www.charlesproxy.com/documentation/proxying/ssl-proxying/ (payant)
Note : Si vous souhaitez un article dédiée à l’interception SSL, prière de m’envoyer la requête dans les commentaires, j’expliquerais le détail de la démarche.

Je fais un saut aux conclusions de mon analyse du flux :

Liste des serveurs avec qui Pokemon GO communique :

Analyse du flux avec Holoholo

Pour comprendre l’humour des gens de NIANTICLABS, je vous invite à visiter le serveur en question sur votre naviguateur : « https://pgorelease.nianticlabs.com/plfe/« , le message explicite suivant s’affiche :
« Dude, this is the Player Frontend. » (Traduit : Mec, c’est la partie Joueur du serveur).
Le titre de la page « Holoholo player frontend » nous rappelle le package « holoholo » vu dans la partie 1 de notre analyse. on va donc appeler notre serveur dorénavant « holoholo ».
Premier constat : Dans le flux, on remarque plusieurs numéros à la suite de l’URL : https://pgorelease.nianticlabs.com/plfe/226 ce numéro est variable si l’on relance l’application. Il s’agit surement de plusieurs sous serveurs ou sous instance du serveurs, qui traitent, en Load Balancing les requêtes des millions de clients. Dans une session de jeu, un numéro est assigné, et toutes les requetes vont et reviennent vers ce numéro.
Deuxième constat : La dernière partie de l’url est la mention « RPC » pour « Remote Procedure Call ». Il s’agit du type de communication avec le serveur. on cherchera donc l’équivalent du XML ou bien du JSON dans les requetes pour comprendre la data envoyée.
Troisième constat : Les requêtes ne sont pas en XML/RPC ni en JSON, il s’agit de chaines de caractère du type suivant :

5‚€€€€ÉßÛS#pgorelease.nianticlabs.com/plfe/226:[
@nrÝZ†¡Ï¯½”'ëXÖÐ_}Î~—ñ÷0'@…Ít‘›-C÷‰
<j8y”Êvâ–9~Ă/§¾ñ¶,s^å†ïúÞ*$Äß.¸ñŒD©nz»fM¢¢

Ce format sérialisé est décodable par MITM ou Charles en utilisant les « protocoles buffers » (plus d’infos ici : https://en.wikipedia.org/wiki/Protocol_Buffers )
La requête décodée donnera donc :


1: 53
2: 6032429073588813826
3: "pgorelease.nianticlabs.com/plfe/226"
7 {
  1: "nr\026\335Z\206\241\317\257\275\224\'\353X\326\320_}\220
  \316~\227\361\3670\'@\205\315t\221\233-C\367\211\r<j8y\024
  \224\312v\342\2269~\304\202/\036\247\276\361\266,\033s\027\006\f^"
  2: 1468599616357
  3: "$\002\304\337.\034\270\361\214D\251nz\273fM"
}
100 {
}
100 {
}

On voit donc l’url claire du serveur qui nous répondra pour le reste de la session : 226.
Pour décoder les \xxxx. Il s’agit d’une représentation en OCTAL des caractères ASCII. cette méthode appelée « Octal Escaping » est une façon de coder des caractères qui ne sont pas mappé à des caractères facilement « typable » via le clavier.

Dans les réponses RPC on remarque des chaines de type :
5075f80e6-760e-4553-96ef-6e117b933969/1467337919227000pm0015øÈÃۓÑÍ%Mú¬(µÆ2´žk—ÃÍUjKÐýhcn
capture_charles
Cette chaine a l’air d’un UUID suivi de plusieurs Attributs. Je suis attiré par la chaine « PM0015 » que j’ai vu plus haut dans la capture. Dans une requête vers le serveur API google : https://storage.googleapis.com/cloud_assets_pgorelease/bundles/android/pm0015
il s’agit des assets d’un objet pm0015 utilisé par unity très probablement et qui se retrouve dans les requête.
JE pense qu’il s’agit des fameux pokemons, PM pour pokemon et 15 pour l’index du pokemon en question (pokemon 15 beedrill : http://www.serebii.net/pokedex-xy/015.shtml)

Conclusion

Alors voilà, j’ai appris beaucoup de choses, et notamment comment lire le code envoyé et recu depuis le serveur, je vois donc la localisation, la localisation des pokemon, mais je ne vois en aucun cas d’autres informations transité, si ce n’est des informations sur le joueur, la situation du pokedex …
donc pour répondre à la question d’un ami, qui m’a donné le courage de faire cet exercice : NON pokemon go n’envoie pas le flux de la caméra vers le serveur !. mais ils vous suivent à la trace, et font beaucoup d’analytics sur vos habitudes geolocalisées 😉
Merci 🙂


Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *