Giovanni Rocca

Giovanni Rocca

Applications developer, Software engineer

Reverse Engineering – Supercell – October update, part 3

Hello everybody and welcome to the third chapter of my Supercell reverse engineering posts chain. As said in the second post of the chain, everything has been so quite till the beginning of october, where a missive update has hit Clash Royale, Clash of Clans and Boom Beach.

New content has been introduced for almost all of the games and also, I’m happy to see some real security actions that has been taken to prevent reverse engineering and binary manipulation. That measures can be found inside Boom Beach, probably implemented only over there to have some feedbacks about the general score and a reaction from the reverse engineering scene.

Analayzing the changes for each game

Clash Royale

The focus of this update was certainly for the content. The new game mode, the quests and all the various changes that has been implemented from Clash Royale development team never really touched the security, which is the main topic of this post. The public server key is changed, as usual, and can be found at offset 5156872.

Clash of Clans

I can’t say that much about the content, since I’m not a CoC player, but I can start spending 2 lines on security changes here. My previously crack, documented in the first post, has been fixed (very softly). The other 2 methods used by private servers owners are left untouched, probably due to the nature of the projects which keep the works in a closed source state. Still wondering why they didn’t diff the modified binary supplied by private servers to prevent that patching too. I would imagine, due to the fix shipped in this new update, that Supercell is aware of my works and probably they are now keeping a better look to my post chain! Anyway, the time needed to found a new little hole to inject a 4 byte payload wasn’t that much.

The new payload injected in the same spot (with a different offset) is now changed to FC68, which translated to ARM assembly would be:

LDR R4, [R7, #0xC]

R7 struct still hold the hardcoded key at position 0xC which we can still use to generate our magic key. Pinocchio has already been updated to patch and proxy it

Boom Beach

Boom Beach is where the real magic happens! Let me go really streight. I’ve reach the goal. As said in my previous posts, my goal/challenge, is on protocol and encryption. The purpose of what I do is reading and understanding protocols and logics, and of course to bypass any kind of encryption if used. Boom Beach has been released with login involved encryption functions obfuscated, with some sort of antitamper which prevent binary modifications (this was really enough…), with something before login that prevent any debugger to be attached to the game process. Any tools that you are going to use on Boom Beach to attempt any kind of actions will be messed up. IDA can’t properly parse login encryption instructions, can’t generate any pseudo-code and functions signature are messed up as well. GDB, which i was used to use until now can’t be attached (maybe :P… I still have a valid solution for it that will se the light once whatever is this named will be shipped with Clash Royale or Clash of Clans). Any attempt to modify the binary will result as well in nothing, the game will just crash and whatever payload you are going to write, it will be re-written, not hard to understand that a checksum or similar method has been added. Once obfuscations has been figured, first good thing… Encryption isn’t changed at all!

Changing the modus operandi

Yeah. Why should I keep touch the binary? I would probably find a way to get rid to whatever is preventing me to inject a payload if i will be forced to, but actually, the goal is to read and understand… so, i wish @Ultrapowa and all his team to find a solution for their project (a lot of respect for him even if his main project is something that I personally don’t like). As said, I would also find a way to properly attach GDB but this time I had fun with Frida and JS.

Obfuscating is terrible

I mean why? I’ve learnt a lot just by translating back a lot of the logic used, why you want to stop people that love to learn?

Oh my lovely Frida…

Looks like we all did forget about Frida? Or maybe not. Even Frida turn out to be a bad way to follow at the beginning. Problem is still that SIGILL with illegal opcode thrown as well when attaching IDA debugger or GDB.

The game is not over yet

Exactly, the game is not over yet. The same crack used on CoC can be used as well on BoomBeach, the 2 offsets can be found easily through all the messed asm and the patch can be applied with notepad++ hexeditor plugin (this was discoveredater) or similar tools. Im gonna close this blog post with a dump from my tools, a public repo can be found on my personal github profile!. Waiting for this on Clash Royale! See you to the next chapter!

 

A better readable dump with code snippet can be found here!


SENT HELLO!

LOGIN!

ENTERING KEYPAIR

LEAVING KEYPAIR!
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 9f 67 08 7c 81 96 48 48 4f 9b ce d7 98 15 ae b7 .g.|..HHO.......
00000010 f8 34 2e 36 14 15 7e 1a b8 a2 35 a4 d8 dc ad 50 .4.6..~...5....P
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 2f e1 c7 59 ef e0 41 22 64 a9 7d cc d0 59 96 a4 /..Y..A"d.}..Y..
00000010 fe e3 d7 a1 51 fb d8 89 16 c7 1c dc 33 b3 3b eb ....Q.......3.;.

UPDATING B2
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 9f 67 08 7c 81 96 48 48 4f 9b ce d7 98 15 ae b7 .g.|..HHO.......
00000010 f8 34 2e 36 14 15 7e 1a b8 a2 35 a4 d8 dc ad 50 .4.6..~...5....P

UPDATING B2
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 81 dc 6b 89 6f b5 c9 36 0a fb 9f 51 41 db ae 21 ..k.o..6...QA..!
00000010 41 c1 ab 94 17 66 84 b0 0b 8e e6 76 29 a8 74 00 A....f.....v).t.

B2 FINISH!
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 18 00 00 00 10 c9 bd f2 67 e6 09 6a 3b a7 ca 84 ........g..j;...
00000010 85 ae 67 bb 2b f8 94 fe 72 f3 6e 3c f1 36 1d 5f ..g.+...r.n<.6._
00000020 3a f5 4f a5 d1 82 e6 ad 7f 52 0e 51 1f 6c 3e 2b :.O......R.Q.l>+
00000030 8c 68 05 9b 6b bd 41 fb ab d9 83 1f 79 21 7e 13 .h..k.A.....y!~.
00000040 19 cd e0 5b 00 00 00 00 00 00 00 00 00 00 00 00 ...[............
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060 00 00 00 00 9f 67 08 7c 81 96 48 48 4f 9b ce d7 .....g.|..HHO...
00000070 98 15 ae b7 f8 34 2e 36 14 15 7e 1a b8 a2 35 a4 .....4.6..~...5.
00000080 d8 dc ad 50 f6 e0 7c 02 b7 28 df ee 9a 84 92 04 ...P..|..(......
00000090 b2 ac 1a 30 04 ae 3c e1 91 09 2a e9 ae 51 88 db ...0..<...*..Q..
000000a0 41 76 85 28 00 00 00 00 00 00 00 00 00 00 00 00 Av.(............
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000c0 00 00 00 00 00 00 00 00 ........

ENTERING NM
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 f9 a3 d2 d5 de cb b9 e0 c7 81 c1 0f f5 ed ad a2 ................
00000010 f0 b9 8b 50 aa 59 df 79 ...P.Y.y

0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 0c 81 48 d4 66 40 7e 47 a7 23 11 b7 ea 03 af 1b ..H.f@~G.#......
00000010 49 a3 bb 0c 0c d4 5f e6 b9 95 24 fa e1 6a 6f d2 I....._...$..jo.

// login encrypted
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 27 75 00 01 81 00 03 9f 67 08 7c 81 96 48 48 4f 'u......g.|..HHO
00000010 9b ce d7 98 15 ae b7 f8 34 2e 36 14 15 7e 1a b8 ........4.6..~..
00000020 a2 35 a4 d8 dc ad 50 cd 69 40 a7 64 48 54 69 7a .5....P.i@.dHTiz
00000030 c4 ad a2 95 32 42 2a d0 4a 37 66 8c cd 85 6b 76 ....2B*.J7f...kv
00000040 fb da f0 cf ba fb c3 8e 24 c1 b2 b4 3b e4 08 5c ........$...;..\
00000050 3b fd 19 b3 c4 9d 2b 97 45 e4 9f 78 7a 88 2d 2c ;.....+.E..xz.-,
00000060 aa 07 19 bf 33 98 13 7f 42 e6 04 9c f5 71 dd 7c ....3...B....q.|
00000070 c7 f0 54 cc c6 60 d3 87 1c 08 82 1c 8f 5a 0d 23 ..T..`.......Z.#
00000080 c4 7f d7 5a 2a 22 bf 79 35 24 56 d5 47 a4 6f 26 ...Z*".y5$V.G.o&
00000090 8e cd 0b 20 05 90 1f cb c4 24 58 37 83 3b 4d a9 ... .....$X7.;M.
000000a0 7f c3 8f 5d e1 55 e7 b7 eb 34 e0 82 41 90 73 a6 ...].U...4..A.s.
000000b0 6f 84 74 89 ab de ea 7a b3 90 25 29 7d 88 d0 63 o.t....z..%)}..c
000000c0 de 23 ec 7d 55 ee 65 bf e9 c6 c0 68 3d 4e 96 90 .#.}U.e....h=N..
000000d0 30 05 d8 88 a2 d6 32 af 21 c8 98 f1 18 22 4d 64 0.....2.!...."Md
000000e0 41 0e 02 67 42 39 05 80 01 38 57 94 74 35 93 37 A..gB9...8W.t5.7
000000f0 a9 84 9a 63 e1 a0 99 52 58 c1 39 50 47 b6 5a 70 ...c...RX.9PG.Zp
00000100 97 08 88 b9 af ec aa cb f7 ad 41 1b 7c a1 c1 e3 ..........A.|...
00000110 8f af f0 d0 2d a4 5c f3 ee fc e4 d3 5b 68 36 5d ....-.\.....[h6]
00000120 db 53 d0 47 a0 b9 0f 6a 29 23 e7 c7 14 29 f8 ce .S.G...j)#...)..
00000130 83 c9 88 96 d9 eb 57 fd 0a 6e 62 cf 22 e2 b8 97 ......W..nb."...
00000140 fa 4d f3 fd 1a 4c ba 3e 4c 7a ee c0 09 7c 77 bc .M...L.>Lz...|w.
00000150 a1 47 7f d4 22 da bb 1d 87 77 2b f6 99 44 bf 14 .G.."....w+..D..
00000160 44 97 b8 f2 a7 5d ea c4 57 39 77 c1 05 1a 23 32 D....]..W9w...#2
00000170 b6 e3 a9 9b f5 54 79 72 4f f7 ca 8a 97 b7 93 63 .....TyrO......c
00000180 ef 6b 75 6d 99 ce 13 08 .kum....

// decrypted
00000004e0000002862396661313536326161363932313562656632376334313037626263373065356433616332633037000000000000001034633363346630623835346630623361000000074c472d48383530001e84840000000569742d49540000002431636261356432312d336139352d343830322d623035392d32353436303331303333343800000003372e30020000000000000010346333633466306238353466306233610000002430646464633864632d646233622d346635632d626233652d3530313431633335316637370000000001000000020000000000000000ffffff88

Reverse Engineering – Supercell – Clash Royale. Part 2

Almost two month later, here we are with the act two of the Supercell reverse engineering post series, if you missed the first one about the new encryption, it can be found here.

Nothing special came in terms of updates on any of the Supercell games after holydays, waiting for the scheduled big one that will hit Clash Royale in the upcoming days and that I’m sure will be fullfit of changes and improvements, also in terms of security and protocol.

During these day, a good old friend, that toke part of that magic PoGo Unknown6 reversing night, join our open community, making me feel really stronger while waiting this new update. He immediatly start exploring something that was already partially reversed a month ago and that end up in a complete reverse, the object of this post. What we are going to explore in details today (at least, what we know about it((((that could also be really wrong)))) is (the ECT) EndClientTurn and (the OHD) OwnHomeData.

Both ECT and OHD are part of Supercell protocol and data exchange system, which is common on all their games. Both of them are messages, which holds data and structures. ECT is used mostly to keep the server and the client synced, to prevent cheats. ECT is sent by the client every 10 seconds and its mostly empty. An ECT is sent on almost all the “user actions” such as opening chests, donating a card, requesting a donation and it’s not empty anymore but instead, it’s filled with data to keep client and server synced. Another variant of ECT is used during battles, which is sent and received through the UDP part of Supercell protocol. OHD instead is one of the bigger message and carry all the data used by the client to build the “game home”, you can imagine the amount of data that can be found inside Clash Royale OHD (Events, all your decks, timestamps for chests, crown chest data and many more things).

Rebuilding ECT payloads wasn’t hard, and this was already done by the awesome guys at RoyaleDevs (Messages repo). The stuck till now was the checksum field built by the client and shipped by ECT (Battle ECT is actually using an unknown different checksum).

How the client build the checksum (method name came from my IDA db, offsets from my device):


.text:C615EA44 buildNormalChecksum ; CODE XREF: buildChecksum+2A↓p
.text:C615EA44 LDR R1, [R0,#64]
.text:C615EA46 LDR.W R0, [R0,#380]
.text:C615EA4A ADD.W R0, R0, R1,LSL#16
.text:C615EA4E BX LR
.text:C615EA4E ; End of function buildNormalChecksum

Once again, dumping these values was quite the faster way to reach the goal. The param which is located in R0 is a struct that should hold OHD data. The 2 fields used to calculate this are the number of cards unlocked by the current player and something that I’ve name ECTSeed. ECTSeed is a value, shipped as second field in OHD, right after the account ID (which is the first 8 bytes), with variable length integer data type. ECTSeed is incremented by 1 sometimes during gametime, I didn’t really go deeper but i can say that is incremented once at every chest received and once every 2 games (but this could be totally wrong). It wasn’t necessary to investigate more since a new login, which will give you a new OHD, will ship the updated ECTSeed. In the meantime, waiting for that new update, we did reversed the full Clash Royale OHD structure, which we will probably open source after the update (we are sure it will change). With that structure, would be possible to create different bots to auto-open chests and auto donations. Did i said we also did the ECT payloads shipped when donating or opening chests right?

Enjoy some chests OHD payloads! Don’t forget to checkout our github projects which are open for contribution!

Clash of Clans – SuperCell new encryption reverse engineering

In this paper I’m going to speak about what I’ve did to reverse engineer the new encryption, using Clash of Clans as base (The logic used to break CoC could be replicated as well on Boom Beach and HayDay that are already shipped with the new encryption).

I’ll skip whatever that’s already known (the previous encryption), as it can be read and understood here: https://github.com/clugh/cocdp/wiki/Protocol (SuperCell shares the same protocol on all the games) and I’m going to focus on what really changes on this new encryption and how the crack has been done and figured out.

The goal, of course, was to break the encryption. Meanings, beeing able to decrypt and encrypt both server and client side to understand and reproduce payloads. You can find the patcher and the proxy server on github.

Tools used:

  • IDA
  • GDB
  • Gef
  • Unicorn emulator
  • Brain

Languages:

  • Python for the patcher
  • Node JS for the proxy server
  • ARM (ARM / Thumb) Assembly to reverse and understand the logic

What’s changed in details and why:

The old encryption was cracked by patching the public server key, that’s hardcoded in the libg and that’s used to feed blake2b update, to build the nonce, and crypto_box beforenm to build the shared key used later to encrypt/decrypt the payload.

First static analysis shown clearly that both the methods (blake2b update and cryptobox / cryptobox_open) was hard modified. Most of the edits done was only on purpose to obfuscate the whole encryption/decryption logic (the code is playing and moving the stackpointer up and down between close instructions). What really mettered can be found on top of what now are 2 big subroutines wrapping most of the encryption/decryption logic. The 2 subroutines involved are now generiting a new key during runtime (the function that build the key is reversed as well, and its mostly obfuscated with control flow flattening) but still feeded with the hardcoded public key as evidenced during debugging.

Hardcoded CoC key:

655a7dc351818e035c2990fb5f27e345064fbe1ea69bfd65f2ea7319943cd000

Key built int runtime:

7eb15f65bdd576619abbd0b0650c45db1020f5ec969fcf48a828424f1bc8d809

Following, this new key built in runtime is used to actually generate the nonce and to build the shared key with cryptobox_beforenm.

What follow, was dumping that new key, still static, and use it to reproduce and encrypt valid requests but of course that wasn’t enough to decrypt what the client send, why?

To build the login message, the official client, build the shared key from the private key generated during encryption logic and that pair with the key generated in runtime. What we know server side is the public key, that’s sent during login and that we can’t use to build the shared key.

So TLDR, patching the hardcoded key as we were used to, will just result in nothing done.

The actual logic

Starting from saying that I’m aware of another very easy method, that has been used by other guys and kept private and that i never ever tought to check since the amount of attention made to keep the things hard, my logic will patch 2 bytes. These 2 offsets has been found by digging in the memory at the entrance of the 2 involed sodium encryption and decryption subs (crypto_box and crypto_box_open). The library is loadint into R11 a struct holding our keys (public and private + the public server key) In more simple words, what the patch is doing, is replacing what’s used to build the shared key and instead of using the private key (that we don’t like because we don’t have on our server side) is using the hardcoded server key, that’s the pointer in memory just after the private one. This way, the shared key would be static and used always for any server proxy encryption and decryption.

  • Note please, if you read how the proxy server has been modded to made it work, you have noticed that is now using a “magic key” as shared key. This magic key was originally built in runtime while i was playing and messing with some values over there. Its basically the result of a beforenm with the 32 bytes key (the 0x72 one) that we were used to patch and the new server public key that’s build in runtime, that we already know.
    This explain why my patcher is still patching the hardcoded public server key with the 0x72 one (that is now mandatory to let the client generate the magic key as well)

The question that will problably jump on the mind is why I’m still patching the hardcoded key. Simple. The 0x72 was patched inside the client during my works and the first magic key that was built was using it. I see no reason to skip patching 32 bytes that will make life harder to baby leechers. Let’s see that magic key as a little signature from me.

The runtime key generation

Some screenshots while working

More to come…

 

If you are interested in the function that pack the new public server key, you can find my java port here.

SmashGAG is our little new app – project.


Hello guys! How are you doing!?


A couple of month have passed now since the end of my adventure with PokéMesh. During these time a lot of things happened in my life, beginning from the birth of my daughter Noelle followed by my new job position in an awesome team for a great company.

In the free time, mainly at the weekend, me and a good old friend started working towards this new project.

Idea

SmashGAG came from an old Facebook page I had in which I’ve shared a couple of Facebook fake conversations using real and fake characters. I searched for a tool to quickly create these kind of memes with ease for a couple of hours and I finally ended up creating my own little app to build them.

Our main goal (that I think we reached) was to use what I’ve learn with PokèMesh and PokémonGO and take it to a new project (no matter which one or the kind). For example, a rest service that uses so and so, the same communication protocol, the security and many other little things.

The source code of my old app to create these Facebook fake conversations got deleted many months ago since it was a dead project, but I took the idea from it to build what we decide to call, SmashGAG.

About the project

SmashGAG is a new app, very similar to 9gags or other meme and fun applications/websites that will let you create facebook, twitter and google search gags. In addition to other kind of similar services (that let you build these kind of meme) the works is done server side and provided through a rest api service. Images are built in the server and use the real Facebook, Twitter and Google css style to reproduce a perfect screenshot. Within the app you can customize lot of thing such as like, comments, reactions and many more things. The app got a local database that will let you create your characters and use it anytime on your gags. You can customize character name, avatar, nickname after the @ for twitter and even choose if you want the little blue V for twitter verified accounts. Hashtags on the status are processed as well and marked with the blue color. You can use the app to prank on your friend or just build gags to share with your friends on your pages.

Additional

Inside the App, you can register for free to remove the watermark on the gags. By registering, you will have a custom profile with a custom nickname and avatar. We are actually work to bring in a follow/likes system that will let you follow other users and rate their gags. Obviously this will take a bit longer since it’s our “weekend project”, but we are happy of the actual result.

Technical notes

The backend is written in node with express and mongoose which manages the rest service and the data. The request and response envelopes are encrypted client side and deciphered by the server using a magic table. This can be cracked with ease… but will also let us catch any abuser with ease (just like PokémonGO). The first client, of course, it’s for Android. Probably we will move to bring live a web an iOS app later.

You can try the app by becoming a beta tester on the Google Play Store using the following link:

https://play.google.com/apps/testing/com.smashgag?authuser=1

You can also join our discord to discuss the project:

https://discord.gg/CwXbxw2

Social references of the project:

Facebook: https://www.facebook.com/smashgag/
Twitter: https://twitter.com/SmashGag
Instagram: https://www.instagram.com/smashgag/

The app will remain in beta stage until the explore and profile sections will let you see and rate gags built by other users.

Let me know for any improvements or problems!

 

Reverse Engineering: LiveScore.com api encryption

Hello everyone!

Everything stated and reported on this post is for study and demonstration purpose.
There is no violation or usage of copyrighted code nor abuse of service. The code snippet that can be found on the post are reversed and made opensource under GPL license.

Platform: LiveScore.com
Api communication: JSON
Security measure: body encrypted


Request from the original client:

URL http://api.livescore.com/~~/app/07/home/soccer/1.0/
Status Complete
Response Code 200 OK
Protocol HTTP/1.1
SSL
Method GET
Kept Alive No
Content-Type text/plain
Client Address /192.168.1.133
Remote Address api.livescore.com/54.246.163.117


Headers:

GET /~~/app/07/home/soccer/1.0/ HTTP/1.1
user-agent LiveScore_Android_App/new_version
Host api.livescore.com
Connection Keep-Alive
Accept-Encoding gzip


What is superclear is that our response is encrypted, as you can notice by making a simple get request opening: http://api.livescore.com/~~/app/07/home/soccer/1.0/

By digging and debugging the code of the Android App (I’m really familiar with JAVA) I was able to reverse engineering the request structure and the decryption method to obtained styled JSON.

The reversed decryption method, that can be found here, takes 2 parameters, the byte array of the body response and an int32 that is a key obtained by the body. The key is obtained from another little function that takes the bytes from 16 to 35 of the response body (first 15 bytes are discarded and used elsewhere since it’s the query expiration) and from 35 to the end is the encrypted JSON.


Here is a little example on how to use the code, that can be ease ported as well to other languages:

byte[] body = response.body().bytes(); // The bytes of the body response
byte[] key = Arrays.copyOfRange(body, 16, 35);
body = Arrays.copyOfRange(body, 35, body.length);
String json = decrypt(body, key);


Big lacks:

  • SSL
  • Encryption/Decryption methods as well as magic bytes are too easy to spot.

Improvements/Fixes:

  • Encryption/Decryption take times and resources. It’s not needed at all except to hide sensitive informations.
  • Implement hashes on headers/request envelopes.
  • Track users for preventing api abuse

 

 

PokéMesh – Inizio e fine di un’avventura

In questo primo articolo del mio sito/curriculum voglio raccontare la mia bellissima esperienza ed avventura con PokéMesh andando a toccare punti ed idee personali e punti tecnici che potrebbero richiedere un livello base di logica di programmazione ed informatica.

Partiamo dal principio, come nasce PokéMesh.

PokéMesh nasce poche settimane dopo la pubblicazione della popolare app Pokémon GO (meta luglio 2016), sviluppata da Niantic con diversi partener, tra i quali Google, che forniva i server, ed ovviamente Nintendo.

Vista la grande popolarità del gioco decisi di proporre l’idea di sviluppare un’applicazione Android a 3 ragazzi, Alvise – Vincenzo – Domenico, con cui ho avuto il piacere di poter lavorare e con cui spero di poter portare a termine altri grandi progetti. Volevo inizialmente realizzare qualcosa di utile e semplice, e fu cosi che iniziammo a realizzare una mappa che era in grado di mostrare i Pokémon nelle vicinanze.

Non ricordo esattamente a chi venne il nome “PokéMesh”, probabilmente a Domenico ma fu chiaramente azzeccato – Poké (Pokémon) Mesh (Rete). Ma iniziamo a scendere un po più nello specifico su come e cosa era necessario fare per poterla realizzare.

Come tutte le applicazioni e i giochi online, anche Pokémon GO ha un client, l’app, e i server, con il quale avviene un costante scambio di dati. Il passaggio dei dati avviene attraverso le api che comunicano usando dei messaggi in Protobuf (molto simile al JSON). Questi messaggi, contengono poi una serie di dati che vengono riprodotti sul gioco. Per scendere ancora di più nel semplice, il gioco richiede dei dati ai server con dei messaggi, il server li verifica e risponde con i dati richiesti.

Nel nostro caso dovevamo ottenere i Pokémon da mostrare sulla mappa ai loro server, in modo da fornire un servizio “reale” e funzionante. Per fare ciò, si è reso necessario sfruttare alcune tecniche di hacking, ad iniziare dal MITM (man in the middle), una tecnica che consente di poter intercettare lo scambio di dati, che come ormai tutte le app è protetto da SSL, tra il client e i server, riuscendo a leggerne e modificarne il contenuto.

Inizialmente rilasciammo l’app sul PlayStore e sul sito web http://www.pokemesh.com. Il successo dell’app fu quasi immediato, anche grazie alla cura che abbiamo dato all’aspetto grafico dell’app e alle sue funzionalità, seppur ancora molto povere. Con grande stupore, dopo alcuni giorni, l’app scalò la classifica globale del Google Play Store, superando inizialmente Amazon, Spotify, Instagram e altre app di rilievo approdando seconda in classifica (il primo posto era ovviamente di Pokémon GO). La gioia durò poche ore, poichè fummo rimossi dallo store per violazione delle policies di Google. Il danno fu minimo. L’app era già cosi popolare che bastò inserire un sistema di aggiornamenti in-app e continuare la distribuzione sul sito. Penso che nessuno all’interno del nostro gruppo abbia mai visto numeri cosi alti in termini di utenza cosi come penso che sarà veramente difficile trovare un’altro progetto che dia tali soddisfazioni (sempre in termine di numeri).

Ma andiamo avanti… Giunti a settembre, Niantic, inizia ad adottare serie contromisure per impedire ad applicazioni (erano veramente tante) non ufficiali, tra cui la nostra, di poter ricevere dati dai propri server.

N.B: Ogni singola app ed ogni singolo utente che richiedeva dati ai loro server, per loro, era un costo, e non indifferente.

La prima seria contromisura fu l’introduzione della Signature, meglio conosciuta come la Unknown6, una “firma” lasciata nel messaggio per richiedere i dati, che veniva verificata dal server e qualora qualcosa non combaciasse, non veniva ritornato alcun dato. Da questo momento in poi si è passati al livello successivo. Servivano tecniche di hacking molto più avanzate ed un livello teorico abbastanza solido per poter riuscire a “crakkare” la loro sicurezza. Fu cosi che nacque una solida community di sviluppatori provenienti da tutto il mondo, Russia, India, Cina, Romania, Brasile, Canada, Belgio ecc ecc ecc. La prima battaglia durò 4 giorni, dove più di 40 sviluppatori all’interno di una chat, condividevano idee e metodi, lavorando insieme per riuscire a riprodurre la signature che era cryptata ed inserita nella richiesta. Si è quindi ricorso al Reverse Engineering per ricostruire l’algoritmo con cui la signature veniva cryptata.

Inutile dire che nel corso dei mesi, gli aggiornamenti alla loro sicurezza sono stati molto accaniti e frequenti. Possiamo dire che non esiste al mondo nessun sistema che non possa essere crakkato, lo puoi rendere difficile ai limiti dell’impossibile tanto da renderlo estenuante poi per chi lo deve crakkare. Se dovessi parlare dei sistemi di sicurezza adottati negli ultimi aggiornamenti a cui ho lavorato, con un linguaggio terra terra, mi troverei un pò in difficoltà.

All’interno della signature erano stati inseriti diversi hash che venivano anch’essi validati dai server. L’algoritmo per generare gli hash era scritto all’interno della libreria nativa, successivamente offuscata con strong.code. Il primo hash ed il secondo hash erano dei long di 128 byte generati utilizzando un salt di 4 byte ottenuto dalla timestamp, inclusa anch’essa nella richiesta, e i byte della posizione dell’utente (latitudine, longitudine ed altitudine). Gli altri 5 hash erano ottenuti dai byte di ogni singola richiesta inclusa nel pacchetto richieste.

Ho smesso di lavorare al progetto da quando è diventato un gioco da ragazzi, per loro, mandarci KO, ed un impresa che richiedeva altre 2/3 settimane di lavoro per riuscire a ritornare operativi. Successivamente ci è stato anche recapitato un C&D che ha definitivamente chiuso ogni ipotesi di aggiornamento futuro.

Ancora più importante del lato economico, questo progetto penso abbia aperto delle porte a tutto il team. Personalmente, oltre ad aver decuplicato le mie competenze, che sperò di poter centuplicare con altri mille progetti nuovi, mi ha insegnato che lavorare in gruppo e unire più cervelli è la chiave per realizzare qualsiasi tipo di lavoro. In 3 sviluppatori ed 1 grafico abbiamo realizzato un’app che teneva una media di 80.000 persone connesse durante le 24/h, 4 milioni o più di richieste al minuto, oltre 8 server in batteria per gestire il traffico che proveniva sia dall’app che dal sito web. Sono emersi molto anche i nostri limiti durante dei tentativi di realizzare delle espansioni del progetto ma sono sicuro che da esse abbiamo imparato moltissimo. Abbiamo utilizzato oltre 4 linguaggi di programmazione per l’intero progetto, che ci ha portato ad imparare le basi del GOlang e ad espandere PHP java e bash scripting per l’automazione.

Vorrei infine concludere questo articolo sottolineando che tutto ciò che abbiamo fatto era nel pieno della legalità, sebbene può sembrare strano che ottenere dati da un server di proprietà altrui sia legale. Diventa illegale quando per ottenere i dati viene utilizzato del codice di proprietà altrui. Il codice da noi utilizzato era pienamente reversato e pubblicato sulla mia repository.