Reverse Engineering – Supercell – part 4

Hello everybody and welcome to the part 4 of my blog post chain about Supercell games reverse engineering! (I start thinking that we should find something new for the intro… My vocabulary is a bit limited).

Almost 20 days after my last post, I’m coming with some great news, personal ones and of course, about some new found we did.
Let me start with a big thanks and welcome to @Fil, that join and helped a lot in the last phew days also with active development on our actual “packet exploring” solution, which is available as usual on github and opensourced under GPL.

As documented in my previous post, Boom Beach came with a great protection which involves multiple “side” of the binary. I can already feel a lot of people thinking hey! wasn’t this what you look for in your previous posts? Didn’t you “challenge” Supercell as well by tweeting your blog posts streight to them? Oh yes I did, and I can swear I’m having a lot of fun and I’m so proud to say (permissions given) that I’ve managed somehow to reach also the Developer from Supercell which care the security of all the game. (I had to bother a lot of people to reach this goal, but in the end..). I met some nice people during this travel (to reach him), first of Tim and Drew which forwarded my messages to the right people, and maybe Scoopr which point him to me after some text exchange. Anyway, this is something that really made me proud and i’m taking this as usual as a big chance to speak with people which can teach you a lot of things.

I can’t say that much of our conversations and, if I have to be totally honest, he didn’t revelead me anything superspecial so everything I’m gonna write and discuss are things found by our researches and works. One of the most important thing I can say is that I been allowed to keep all of this and… I think he challenged me as well or kind of? So, forgive what I said in my last blog post about “stop touching the bin”. Our solution to “proxy”, which is not really a proxy but instead I would call it “a polite and non intrusive way to read” things, should already be fixed according to what I heard, or anyway, it will need a rework. Let’s start with topics:

The compiler

I cant actually remember if I stated this on my last post or on Discord only, however the very first thing i tought when opening Boom Beach was “Ok.. should be clang and some sort of custom llvm plugin either paid or self developed”. There are a lot of new things which protect the binary now which are:
Strings encryption, Login involved subroutines obfuscated, strong antitamper for either binary and memory.

The strings

Strings are the less usefull things we would ever need, however, I toke this as a serious challenge (which i didn’t won). I did a lot of tests but unfortunately i can’t provide a valid answer to your questions. We did found an ELF initialization table, which is run even before JNI_OnLoad (which is something new as well) that will probably contains everything needed to understand how the strings are encrypted. No way to dump anything either with frida or with GDB. The very first subroutine, which is call by the exported function GameApp_init, got the Strings already in place but also, looking at JNI_OnLoad, which is invoked during loading time, you can see a call to another sub, which is a Log function, and which is taking as input a string encrypted (highliting that things happens even before, we believe in this ELF init table (offset: 0x49A804 of the ARM library (thanks @Fil <3))). We stopped here, in any case, string are fine readable in memory!

Obfuscation and anti tampering

Obfuscation, as I documented in the previous post, was the last of the problem. Lot of jumps and dead instructions with relevant code mixed between the ASM. The anti tampering however is the real “enemy” in this scenario. My previous paper document how the game was “reacting” to a standard patch we were using to do (with dd either or whatever tool to write payloads), with a SIGILL signal followed by the crash of the game.

I’ve managed to “skip” these CRC routines thanks to frida, which can detach and attach himself so that we didn’t really go deeper in trying to figure out what was going on, until Supercell security engineer came to my discord of course!

We didn’t find in the deep where exactly the CRC is done (and so, we can’t really say if there is one or more then one), but with a lot of tests we managed to understand it a bit and let the game go on without SIGILL crash. Whatever I will say now could be right but also very wrong since we didn’t have yet a valid exploit to abuse it, but our tests confirm what I will say now:

The CRC function is taking 4 bytes as range (or maybe 8. We did success with 4). A quick example would be:

[code_block_prettify]00251C68[/code_block_prettify]

Which translated to ARM ASM would be:

[code_block_prettify]MOVS R5, #0
LDR R4, [R3][/code_block_prettify]

Not really need the ASM but instead, let’s take a better look at the buffer;

we have – 00 25 1C 68

00 + 25 + 68 = 93

Any decimal number, will be threat as a decimal number! so we can guess that the CRC function is doing something like:

parseInt(byteHexString //like… “25”);

Instead, 1C will be converted to decimal, which is 28 and so, 93 + 28 will be 121.

Now, if you inject in the same offset, 2 different instructions which the sum (following our parseInt rule) is 121, you will enjoy a nice Boom Beach loading screen. Once knowing this, would just be a metter of time to find a proper payload, which could abuse the troll subroutines of debug menu (that can be rewritten as per our needed).

Im very very fine with my little packet dumper, but if anyone toke this too serious and blame me for Supercell actions to prevent binary modifications, I’m now giving you something to get your **** back and, to make you crying less, I will give you some more spot that you can abuse:

  • Abusing /dev/urandom. Keypair (private key) and the nonce for subsequent login is built with /dev/urandom. What would happens if it will suddenly return 32 bytes of known bytes?
  • Abusing the keypair sub. Keypair subroutine is GOLD! I can list at least 30 ways to crack it. How about writing the same key in both the pointers? IDK use your fantasy!

Thanks for following me and thanks again for taking the time to reach and discuss A LOT of things with me!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.