daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

google-ctf-2018-shall-we-play-a-game.md (5100B)


      1 ---
      2 title: "Google CTF 2018 - Shall We Play a Game?"
      3 section: "Mobile"
      4 sectionSlug: "mobile-pentesting"
      5 sourcePath: "src/mobile-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/mobile-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Google CTF 2018 - Shall We Play a Game?
     14 
     15 The original Google CTF repository preserves the 2018 challenges, and community write-ups preserve this APK and its reversing workflow.<sup>[[1]](#references)[[2]](#references)</sup>
     16 
     17 Upload the APK to an isolated emulator service such as Appetize.io, or install it on a disposable local emulator/device, to observe its behavior:<sup>[[3]](#references)</sup>
     18 
     19 ![Appetize.io emulator running the Shall We Play a Game APK](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28421%29.png)
     20 
     21 The game requires 1,000,000 wins to reveal the flag.
     22 
     23 Following the [Android pentesting](/hacktricks/mobile-pentesting/android-app-pentesting/overview) workflow, decode the APK with Apktool and inspect decompiled Java with JADX.<sup>[[2]](#references)</sup>
     24 
     25 Reading the java code:
     26 
     27 ![Google CTF 2018 - Shall We Play a Game?: Reading the java code](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28495%29.png)
     28 
     29 The function that prints the flag is `m()`.
     30 
     31 ## **Smali changes**
     32 
     33 ### **Call m() the first time**
     34 
     35 To make the application call `m()` when `this.o != 1000000`, invert the branch condition:
     36 
     37 ```text
     38  if-ne v0, v9, :cond_2
     39 ```
     40 
     41 to:
     42 
     43 ```text
     44  if-eq v0, v9, :cond_2
     45 ```
     46 
     47 ![Before](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28383%29.png)
     48 
     49 ![After](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28838%29.png)
     50 
     51 Follow the [Android pentesting](/hacktricks/mobile-pentesting/android-app-pentesting/overview) workflow to rebuild and sign the APK, then run it again:
     52 
     53 ![Appetize.io emulator showing the modified APK after changing the Smali condition](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28128%29.png)
     54 
     55 The displayed flag is not fully decrypted because the per-win transformation must run 1,000,000 times; merely bypassing the comparison does not reproduce those iterations.<sup>[[2]](#references)</sup>
     56 
     57 Another approach is to leave the branch instruction intact and change its operands:
     58 
     59 ![Alternative Smali change: keep the branch instruction and change the compared registers](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28840%29.png)
     60 
     61 **Another way** is instead of comparing with 1000000, set the value to 1 so this.o is compared with 1:
     62 
     63 ![Smali changes - Call m() the first time: Another way is instead of comparing with 1000000, set the value to 1 so this.o is compared with 1](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28629%29.png)
     64 
     65 A fourth approach is to move the value of `v9` (1,000,000) into `v0` (`this.o`):
     66 
     67 ![Smali changes - Call m() the first time: A forth way is to add an instruction to move to value of v9(1000000) to v0 (this.o)](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28414%29.png)
     68 
     69 ![Smali changes - Call m() the first time: A forth way is to add an instruction to move to value of v9(1000000) to v0 (this.o)](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28424%29.png)
     70 
     71 ## Solution
     72 
     73 Make the application run the win/decryption loop **1,000,000 times** after the first win. Create the `:goto_6` loop and jump back while `this.o` has not reached 1,000,000:<sup>[[2]](#references)</sup>
     74 
     75 ![Call m() the first time - Solution: Make the application run the loop 100000 times when you win the first time. To do so, you only need to create the :goto 6 loop and make the...](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%281090%29.png)
     76 
     77 The original experiment succeeded on a physical device but not its emulator. That is an observation about that setup rather than an inherent requirement; emulator CPU speed, watchdogs, or service limits can make the million-iteration loop appear to hang.
     78 
     79 ## References
     80 
     81 - [1] [Google CTF challenge repository](https://github.com/google/google-ctf/tree/master/2018)
     82 - [2] [CTFtime — Google CTF 2018 “Shall we play a game?” write-up](https://ctftime.org/writeup/10277)
     83 - [3] [Appetize.io Android emulator](https://appetize.io/)