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  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  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  48 49  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  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  60 61 **Another way** is instead of comparing with 1000000, set the value to 1 so this.o is compared with 1: 62 63  64 65 A fourth approach is to move the value of `v9` (1,000,000) into `v0` (`this.o`): 66 67  68 69  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  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/)