{"id":229,"date":"2016-07-26T23:59:26","date_gmt":"2016-07-26T23:59:26","guid":{"rendered":"http:\/\/www.erroussafi.com\/blog\/?p=229"},"modified":"2018-08-07T12:43:45","modified_gmt":"2018-08-07T11:43:45","slug":"analyse-de-pokemon-go-part-2-analyse-reseau","status":"publish","type":"post","link":"https:\/\/www.erroussafi.com\/index.php\/2016\/07\/26\/analyse-de-pokemon-go-part-2-analyse-reseau\/","title":{"rendered":"Analyse de Pokemon GO ! (Part 2 : Analyse R\u00e9seau)"},"content":{"rendered":"<p>Dans la premi\u00e8re partie de l&#8217;analyse de l&#8217;application &#8220;Pokemon Go&#8221;, nous avons vu les composants du fichier d&#8217;installation, et nous avons d\u00e9compil\u00e9 le projet afin de comprendre les d\u00e9pendances de l&#8217;application. Ceci nous a renseign\u00e9 sur beaucoup de choses. Afin d&#8217;avancer dans l&#8217;analyse, il faudra regarder ce que fait l&#8217;application sur le r\u00e9seau. C&#8217;est l&#8217;objectif de cette seconde et derni\u00e8re partie.<br \/>\n<!--more--><\/p>\n<h3>Pk le\u00a0bluetooth ?<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft\" src=\"http:\/\/media.nintendo.com\/e3\/e3-assets\/images\/games\/pokemon-go-plus\/screenshots\/screenshot_2-768.jpg\" width=\"261\" height=\"260\" \/>Lors de l&#8217;analyse du code d\u00e9compil\u00e9, je me suis rendu compte que la majorit\u00e9 du code du jeu r\u00e9side \u00e0 l&#8217;interieur du framework unity. Unity est utilis\u00e9e par les cr\u00e9ateurs de jeux vid\u00e9o pour cr\u00e9er des jeux qui soit potentiellement executable sur plusieurs plateformes (web, ios, android, &#8230;). Ce qui veut dire que ce qui reste du code Android sont les choses impossible \u00e0 faire via Unity.<br \/>\nUn grand nombre de classes interagissent avec les capacit\u00e9s bluetooth de l&#8217;appareil et notamment \u00e0 l&#8217;interieur du \u00a0package\u00a0com.nianticproject.holoholo.sfida.<br \/>\nUne recherche internet m&#8217;a permis de voir cet <a href=\"https:\/\/www.google.com\/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=1&amp;cad=rja&amp;uact=8&amp;ved=0ahUKEwihre_pmpLOAhVCAxoKHQMmAlEQFggcMAA&amp;url=http%3A%2F%2Fwww.pokemongo.com%2Fen-us%2Fpokemon-go-plus%2F&amp;usg=AFQjCNEQ6rdfuCZolQQ5ROmHXdbnRwyB1Q&amp;sig2=fc3R5JkX4OslhF5oSzbQBg&amp;bvm=bv.128153897,d.bGs\">appareil <\/a>qui fait partie du merchandising Nintendo (voir photo \u00e0 cot\u00e9). Il s&#8217;agit d&#8217;un petit appareil IoT qui permet notemment d&#8217;alerter l&#8217;utilisateur sur l&#8217;existance de pokemon \u00e0 cot\u00e9, sans avoir \u00e0 sortir constamment son t\u00e9l\u00e9phone. Ce business fait partie des choses sur lesquelles mise nintendo pour mon\u00e9tiser l&#8217;application et le monde des pokemon GO.<\/p>\n<p>Voici une liste de m\u00e9thodes vue dans le code qui d\u00e9crivent les interaction avec l&#8217;appareil Go plus :<\/p>\n<pre>boolean notifyCancelDowser();\r\nboolean notifyError();\r\nboolean notifyFoundDowser();\r\nboolean notifyNoPokeball();\r\nboolean notifyPokeballShakeAndBroken(String str);\r\nboolean notifyPokemonCaught();\r\nboolean notifyProximityDowser(String str);\r\nboolean notifyReachedPokestop(String str);\r\nboolean notifyReadyForThrowPokeball(String str);\r\nboolean notifyRewardItems(String str);\r\nboolean notifySpawnedLegendaryPokemon(String str);\r\nboolean notifySpawnedPokemon(String str);\r\nboolean notifySpawnedUncaughtPokemon(String str);\r\nboolean notifyStartDowser();\r\n<\/pre>\n<p>Tr\u00e8s interessant ! on sait maintenant quel type de notifications sont envoy\u00e9 depuis l&#8217;application vers le Pokemon Go Plus. Si vous vous sentez l&#8217;ame d&#8217;un maker potentiel ! il serait possible de cr\u00e9er votre propre appareil ! moins cher biens\u00fbr que les\u00a0$34.99 USD de Nintendo \ud83d\ude42<br \/>\nPour information, l&#8217;appareil sera officiellement disponible \u00e0 la vente \u00e0 partir du 31 Juillet. Mais on sait d\u00e9j\u00e0 ce qu&#8217;il peut faire !<br \/>\nBonus \u00a0: Dump des s\u00e9quences bluetooth des notifications<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"\" src=\"https:\/\/applidium.com\/en\/news\/unbundling_pokemon_go\/constants_pk.png?14689527\" width=\"664\" height=\"469\" \/><\/p>\n<h3>Analyse sommaire du flux<\/h3>\n<p>Nous y sommes. Pour les initi\u00e9s d&#8217;entre vous, on sait que Pokemon Go communique avec internet ! Notemment pour avoir les positions des Pokemons \u00e0 afficher sur la carte \u00e0 l&#8217;itnerieur du jeu, mais aussi pour mettre \u00e0 jour le profil du joueur avec les pokemons captur\u00e9s, la position GPS &#8230; etc.<br \/>\nMa premi\u00e8re tentative \u00e9tait de capturer le flux &#8220;brut&#8221; de communication de l&#8217;application avec internet. Pour faire cel\u00e0, je vous conseille l&#8217;excellente application <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=lv.n3o.shark&amp;hl=en\">&#8220;Shark for root&#8221; disponible sur l&#8217;app store<\/a>. Seule complication : il faut absolument que votre t\u00e9l\u00e9phone soit root\u00e9 pour que l&#8217;application puisse &#8220;sniffer&#8221; le flux r\u00e9seau et le capturer sous format .CAP lisible sur PC avec le logiciel <a href=\"https:\/\/www.wireshark.org\/\">Wireshark <\/a>par exemple, ou tout autre analyseur de protocole compatible format\/librairie PCAP.<br \/>\nJ&#8217;ai donc captur\u00e9 une session sur Pokemon GO (fichier pcap filtr\u00e9 disponible ici : )<br \/>\nUne premi\u00e8re analyse en filtrant les requ\u00eate &#8220;DNS&#8221; m&#8217;oriente vers le serveur : pgorelease.nianticlabs.com qui est r\u00e9solu vers l&#8217;adresse : 130.211.14.80<br \/>\nJe filtre ensuite sur l&#8217;adresse IP et je vois des \u00e9changes (comme pr\u00e9vu) crypt\u00e9 en TLS (HTTPS\/SSL) avec un flux illisible (voir capture).<br \/>\n<a href=\"http:\/\/www.erroussafi.com\/blog\/index.php\/2016\/07\/26\/analyse-de-pokemon-go-part-2-analyse-reseau\/capture_trace\/\" rel=\"attachment wp-att-233\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-233\" src=\"https:\/\/www.erroussafi.com\/wp-content\/uploads\/2016\/07\/capture_trace.png\" alt=\"capture_trace\" width=\"928\" height=\"582\" \/><\/a><\/p>\n<h3>D\u00e9cryptage du traffic<\/h3>\n<p>Internet moderne est tr\u00e8s s\u00e9curis\u00e9, l&#8217;ensemble du traffic est crypt\u00e9, il est m\u00eame impossible en effectuant une capture locale (faite dans le paragraphe pr\u00e9c\u00e9dent) de d\u00e9crypter le flux, \u00e0 moins de disposer de la cl\u00e9 priv\u00e9e de la transaction SSL.<br \/>\nCependant, et puisque nous disposons du t\u00e9l\u00e9phone dont le flux est \u00e0 d\u00e9crypter, une technique de hacking\u00a0existe de type du &#8220;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Man-in-the-middle_attack\">man in the middle attack<\/a>&#8220;.<br \/>\nEn gros, nous allons nous mettre entre le t\u00e9l\u00e9phone et internet. Pour cel\u00e0 nous avons besoin de cr\u00e9er un Proxy HTTPS. Son r\u00f4le sera, \u00e0 la r\u00e9c\u00e9ption d&#8217;une requete de l&#8217;application, la d\u00e9crypter en utilisant la cl\u00e9 cot\u00e9 application, la crypter avec la cl\u00e9 cot\u00e9 serveur, attendre une r\u00e9ponse du serveur, la d\u00e9crypter avec la cl\u00e9 cot\u00e9 serveur, la crypter avec la cl\u00e9 cot\u00e9 application, et l&#8217;envoyer vers le t\u00e9l\u00e9phone.<br \/>\nAfin que le proxy puisse \u00eatre utilis\u00e9 par notre t\u00e9l\u00e9phone de test, nous allons forger un certificat et l&#8217;installer au niveau du t\u00e9l\u00e9phone. Ceci permettera au t\u00e9l\u00e9phone de faire confiance \u00e0 notre serveur domestique et l&#8217;utiliser comme proxy HTTPS. Les outils pour faire cel\u00e0 :\u00a0<a href=\"https:\/\/mitmproxy.org\/\">https:\/\/mitmproxy.org\/<\/a> (gratuit), ou\u00a0https:\/\/www.charlesproxy.com\/documentation\/proxying\/ssl-proxying\/ (payant)<br \/>\nNote : Si vous souhaitez un article d\u00e9di\u00e9e \u00e0 l&#8217;interception SSL, pri\u00e8re de m&#8217;envoyer la requ\u00eate dans les commentaires, j&#8217;expliquerais le d\u00e9tail de la d\u00e9marche.<\/p>\n<h4>Je fais un saut aux conclusions de mon analyse du flux :<\/h4>\n<h4>Liste des serveurs avec qui Pokemon GO communique :<\/h4>\n<ul>\n<li><a href=\"https:\/\/android.clients.google.com\/c2dm\/register3\">https:\/\/android.clients.google.com\/c2dm\/register3<\/a> :\u00a0API le push<\/li>\n<li><a href=\"https:\/\/stats.unity3d.com\/HWStatsUpdate.cgi\">https:\/\/stats.unity3d.com\/HWStatsUpdate.cgi<\/a> : Comme son nom l&#8217;indique : Encore des analytics Unity<\/li>\n<li><a href=\"https:\/\/bootstrap.upsight-api.com\/config\/v1\/a9cc12f87adc420baf964f187672ecb4\/\">https:\/\/bootstrap.upsight-api.com\/config\/v1\/a9cc12f87adc420baf964f187672ecb4\/<\/a> :\u00a0Analytics de upsight<\/li>\n<li><a href=\"https:\/\/appload.ingest.crittercism.com\/v0\/appload\">https:\/\/appload.ingest.crittercism.com\/v0\/appload<\/a> :\u00a0Analytics de Crittercism<\/li>\n<li><strong><a href=\"https:\/\/pgorelease.nianticlabs.com\/plfe\/rpc\">https:\/\/pgorelease.nianticlabs.com\/plfe\/rpc<\/a> :\u00a0Nous avons vu cet URL plus haut, il s&#8217;agit de celui qui nous interesse et qui consolide la majorit\u00e9 des interactions avec le r\u00e9seau<\/strong><\/li>\n<li><a href=\"https:\/\/play.googleapis.com\/log\">https:\/\/play.googleapis.com\/log<\/a> :\u00a0API Play Services<\/li>\n<li><a href=\"http:\/\/lh4.ggpht.com\/LakctgAXpXwe-3PMCWws8rCoVn1_TmyfAiWjWXm6VtsRjRl5v53n1JrWBumWmldzsBFxIUdRLXgsMewLjuyN\">http:\/\/lh4.ggpht.com\/<\/a>:\u00a0ce serveur abrite des images picasa, il s&#8217;agit d&#8217;une image d&#8217;un pokestop dans les environs.<\/li>\n<li><a href=\"https:\/\/www.google.com\/loc\/m\/api\">https:\/\/www.google.com\/loc\/m\/api<\/a> :\u00a0API de Geolocalisation de Google.<\/li>\n<\/ul>\n<h4>Analyse du flux avec\u00a0Holoholo<\/h4>\n<p>Pour comprendre l&#8217;humour des gens de NIANTICLABS, je vous invite \u00e0 visiter le serveur en question sur votre naviguateur : &#8220;<a href=\"https:\/\/pgorelease.nianticlabs.com\/plfe\/\">https:\/\/pgorelease.nianticlabs.com\/plfe\/<\/a>&#8220;, le message explicite suivant s&#8217;affiche :<br \/>\n&#8220;Dude, this is the Player Frontend.&#8221; (Traduit : Mec, c&#8217;est la partie Joueur du serveur).<br \/>\nLe titre de la page &#8220;Holoholo player frontend&#8221; nous rappelle le package &#8220;holoholo&#8221; vu dans la partie 1 de notre analyse. on va donc appeler notre serveur dor\u00e9navant &#8220;holoholo&#8221;.<br \/>\nPremier constat : Dans le flux, on remarque plusieurs num\u00e9ros \u00e0 la suite de l&#8217;URL :\u00a0https:\/\/pgorelease.nianticlabs.com\/plfe\/226 ce num\u00e9ro est variable si l&#8217;on relance l&#8217;application. Il s&#8217;agit surement de plusieurs sous serveurs ou sous instance du serveurs, qui traitent, en Load Balancing les requ\u00eates des millions de clients. Dans une session de jeu, un num\u00e9ro est assign\u00e9, et toutes les requetes vont et reviennent vers ce num\u00e9ro.<br \/>\nDeuxi\u00e8me constat : La derni\u00e8re partie de l&#8217;url est la mention &#8220;RPC&#8221; pour &#8220;Remote Procedure Call&#8221;. Il s&#8217;agit du type de communication avec le serveur. on cherchera donc l&#8217;\u00e9quivalent du XML ou bien du JSON dans les requetes pour comprendre la data envoy\u00e9e.<br \/>\nTroisi\u00e8me constat : Les requ\u00eates ne sont pas en XML\/RPC ni en JSON, il s&#8217;agit de chaines de caract\u00e8re du type suivant :<\/p>\n<pre><code>5\u0082\u0080\u0080\u0080\u0080\u00c9\u00df\u00dbS#pgorelease.nianticlabs.com\/plfe\/226:[\r\n@nr\u00ddZ\u0086\u00a1\u00cf\u00af\u00bd\u0094'\u00ebX\u00d6\u00d0_}\u0090\u00ce~\u0097\u00f1\u00f70'@\u0085\u00cdt\u0091\u009b-C\u00f7\u0089\r\n&lt;j8y\u0094\u00cav\u00e2\u00969~\u00c4\u0082\/\u00a7\u00be\u00f1\u00b6,s^\u00e5\u0086\u00ef\u00fa\u00de*$\u00c4\u00df.\u00b8\u00f1\u008cD\u00a9nz\u00bbfM\u00a2\u00a2\r\n<\/code><\/pre>\n<p>Ce format s\u00e9rialis\u00e9 est d\u00e9codable par MITM ou Charles en utilisant les &#8220;protocoles buffers&#8221; (plus d&#8217;infos ici :\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Protocol_Buffers\">https:\/\/en.wikipedia.org\/wiki\/Protocol_Buffers<\/a> )<br \/>\nLa requ\u00eate d\u00e9cod\u00e9e donnera donc :<\/p>\n<pre><code>\r\n1: 53\r\n2: 6032429073588813826\r\n3: \"pgorelease.nianticlabs.com\/plfe\/226\"\r\n7 {\r\n  1: \"nr\\026\\335Z\\206\\241\\317\\257\\275\\224\\'\\353X\\326\\320_}\\220\r\n  \\316~\\227\\361\\3670\\'@\\205\\315t\\221\\233-C\\367\\211\\r&lt;j8y\\024\r\n  \\224\\312v\\342\\2269~\\304\\202\/\\036\\247\\276\\361\\266,\\033s\\027\\006\\f^\"\r\n  2: 1468599616357\r\n  3: \"$\\002\\304\\337.\\034\\270\\361\\214D\\251nz\\273fM\"\r\n}\r\n100 {\r\n}\r\n100 {\r\n}<\/code><\/pre>\n<p>On voit donc l&#8217;url claire du serveur qui nous r\u00e9pondra pour le reste de la session : 226.<br \/>\nPour\u00a0d\u00e9coder les \\xxxx. Il s&#8217;agit d&#8217;une repr\u00e9sentation en OCTAL des caract\u00e8res ASCII. cette m\u00e9thode appel\u00e9e &#8220;Octal Escaping&#8221; est une fa\u00e7on de coder des caract\u00e8res qui ne sont pas mapp\u00e9 \u00e0 des caract\u00e8res facilement &#8220;typable&#8221; via le clavier.<\/p>\n<p>Dans les r\u00e9ponses RPC on remarque des chaines de type :<br \/>\n5075f80e6-760e-4553-96ef-6e117b933969\/1467337919227000\u0012\u0006<strong>pm0015<\/strong>\u0018\u00f8\u00c8\u00c3\u00db\u0093\u00d1\u00cd\u0002%\u0016M\u00fa\u00ac(\u00b5\u00c6\u00132\u0010\u00b4\u009ek\u0097\u00c3\u00cdUj\bK\u00d0\u0015\u00fdhcn<br \/>\n<a href=\"http:\/\/www.erroussafi.com\/blog\/index.php\/2016\/07\/26\/analyse-de-pokemon-go-part-2-analyse-reseau\/capture_charles\/\" rel=\"attachment wp-att-234\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-234\" src=\"https:\/\/www.erroussafi.com\/wp-content\/uploads\/2016\/07\/capture_charles.png\" alt=\"capture_charles\" width=\"519\" height=\"209\" \/><\/a><br \/>\nCette chaine a l&#8217;air d&#8217;un UUID suivi de plusieurs Attributs. Je suis attir\u00e9 par la chaine &#8220;PM0015&#8221; que j&#8217;ai vu plus haut dans la capture. Dans une requ\u00eate vers le serveur API google :\u00a0https:\/\/storage.googleapis.com\/cloud_assets_pgorelease\/bundles\/android\/pm0015<br \/>\nil s&#8217;agit des assets d&#8217;un objet pm0015 utilis\u00e9 par unity tr\u00e8s probablement et qui se retrouve dans les requ\u00eate.<br \/>\nJE pense qu&#8217;il s&#8217;agit des fameux pokemons, PM pour pokemon et 15 pour l&#8217;index du pokemon en question (pokemon 15 beedrill :\u00a0<a href=\"http:\/\/www.serebii.net\/pokedex-xy\/015.shtml\">http:\/\/www.serebii.net\/pokedex-xy\/015.shtml<\/a>)<\/p>\n<h4>Conclusion<\/h4>\n<p>Alors voil\u00e0, j&#8217;ai appris beaucoup de choses, et notamment comment lire le code envoy\u00e9 et recu depuis le serveur, je vois donc la localisation, la localisation des pokemon, mais je ne vois en aucun cas d&#8217;autres informations transit\u00e9, si ce n&#8217;est des informations sur le joueur, la situation du pokedex &#8230;<br \/>\ndonc pour r\u00e9pondre \u00e0 la question d&#8217;un ami, qui m&#8217;a donn\u00e9 le courage de faire cet exercice : NON pokemon go n&#8217;envoie pas le flux de la cam\u00e9ra vers le serveur !. mais ils vous suivent \u00e0 la trace, et font beaucoup d&#8217;analytics sur vos habitudes geolocalis\u00e9es \ud83d\ude09<br \/>\nMerci \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans la premi\u00e8re partie de l&#8217;analyse de l&#8217;application &#8220;Pokemon Go&#8221;, nous avons vu les composants du fichier d&#8217;installation, et nous avons d\u00e9compil\u00e9 le projet afin de comprendre les d\u00e9pendances de l&#8217;application. Ceci nous a renseign\u00e9 sur beaucoup de choses. Afin d&#8217;avancer dans l&#8217;analyse, il faudra regarder ce que fait l&#8217;application sur le r\u00e9seau. C&#8217;est l&#8217;objectif [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":545,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[9],"tags":[10],"class_list":["post-229","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technique","tag-featured"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.erroussafi.com\/wp-content\/uploads\/2016\/07\/pokemongo2.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/posts\/229","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/comments?post=229"}],"version-history":[{"count":0,"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/posts\/229\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/media\/545"}],"wp:attachment":[{"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/media?parent=229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/categories?post=229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.erroussafi.com\/index.php\/wp-json\/wp\/v2\/tags?post=229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}