The Keys to the Quizdom

Introduction

Quizdom is currently the most popular quiz game for mobile platforms in Greece with more than 500k downloads and it’s surely quite addictive. But what is even more addictive is digging into Android applications and see what interesting things you can find… even in a quiz game.

The devil is in the detail

The quest began when the intercepting proxy caught some strange API calls. The output (Figure 1) suggested that there was some form of encryption in use.

quizdom_api_call

Figure 1 – A typical Quizdom API call

I extracted the APK file in order to search for the encryption scheme. Using a combination of dex2jar and JD-GUI  the extracted code was readable enough since no obfuscation(!) was used. After a quick search using some common keywords (such as “encrypt”,”decrypt” etc.)  the class responsible for the crypto part of the application was detected (Fig 2).

apicrypter_jdgui_edit

Figure 2 – Class responsible for encrypting API calls and decrypting responses

Lo and behold! Hard-coded encryption key and IV! Since the cipher is also known (AES/CBC/PKCSS5padding), decrypting the API calls would be fairly trivial. However, decryption attempts failed over and over again. Something wasn’t right. This lead me to try another path, the path of pure Dalvik decompilation. Using Androguard‘s DAD decompiler the results where a little bit different (Figure 3).

apicrypter_androguard_edit

Figure 3 – Same class when decompiled with DAD decompiler

There is a call to a method named stringTransform which didn’t show up in the previous decompilation attempt. Switching back to JD-GUI (Fig.4) I noticed that the decompilation of Tools.class  resulted in an error, so references to method named stringTransform probably never decompiled properly.

tools_jdgui

Figure 4 – Tools class failed to decompiled when using dex2jar

stringTransform was performing some byte-level operations on both the key and IV. Using the “transformed” strings I was finally able to decrypt API calls and responses.

stringtransform_androguard

Figure 5 – stringTransform generated the final key and IV

The answer to every question

After some navigation through the app and a few games played I had collected almost all possible API calls/responses.

In the beginning of each round,  the application server sends all required information in a quite large JSON-formatted response, including the answers to this round’s questions (Fig. 6,7). This behaviour is very common in mobile games and applications since constantly sending data back and forth is prone to multiple problems (connectivity issues, poor user experience etc.).

answer

Figure 6 – Quizdom’s encrypted response. The answer is somewhere in here.

 

quizdom_decrypted_answer

Figure 7 – Decrypted Response

 

Without further ado, I present you a plugin for mitmproxy (probably the most straight-forward tool for that purpose) which has the answer to every Quizdom question.

Conclusion

First things first. Always prefer native decompilers.

Understanding your threat model is essential to plan a proper protection scheme. In the case of Quizdom  no actual sensitive information is transmitted and no profit can be made by abusing the application (oh really?). So, some trade-offs between security and usability are totally understandable. After all, it’s a mobile game and mobile games should be playable almost everywhere.

But somehow you need to protect your game from cheaters. A simple encrypted API might be the way to go. However with the appropriate time and skill such schemes will fail sooner or later. In order to discourage any wannabe Quizdom know-it-alls and cheaters in general you have to make their job a bit more difficult. This means :

  • Source code obfuscation – Although security through obscurity has failed as an approach, it takes significantly more time to reverse engineer an obfuscated application. ProGuard is a quite reliable solution and very easy to implement.
  • No hardcoded keys or IVs – Implementing a robust crypto scheme takes time, but storing your keys, un-obfuscated in plaintext form inside your source code is heading towards the opposite direction.
  • Do not trust before you verify – The internet is full of bad crypto advice. DO NOT copy-paste code before you verify that it actually works :)

 

P.S We ‘re glad to announce that the Quizdom team has acknowledged our comments and has moved towards a more secure implementation!

 

-Paris Zoumpouloglou

Comments are closed.