Google CTF 2018 - Shall We Play a Game?

Μάθετε το χάκινγκ του AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks:

Κατεβάστε το APK εδώ:

Θα ανεβάσω το APK στο https://appetize.io/ (δωρεάν λογαριασμός) για να δω πώς συμπεριφέρεται το apk:

Φαίνεται ότι πρέπει να κερδίσετε 1000000 φορές για να πάρετε τη σημαία.

Ακολουθώντας τα βήματα από το pentesting Android μπορείτε να ανακατασκευάσετε την εφαρμογή για να πάρετε τον κώδικα smali και να διαβάσετε τον κώδικα Java χρησιμοποιώντας το jadx.

Ανάγνωση του κώδικα Java:

Φαίνεται ότι η συνάρτηση που θα εκτυπώσει τη σημαία είναι η m().

Αλλαγές στον κώδικα Smali

Κλήση της m() την πρώτη φορά

Ας κάνουμε την εφαρμογή να καλεί την m() εάν η μεταβλητή this.o != 1000000, για να το κάνουμε αυτό, απλά αλλάξτε τη συνθήκη:

if-ne v0, v9, :cond_2

Το παρακάτω είναι περιεχόμενο από ένα βιβλίο για χακινγκ σχετικά με τεχνικές χακινγκ. Το παρακάτω περιεχόμενο είναι από το αρχείο /hive/hacktricks/mobile-pentesting/android-app-pentesting/google-ctf-2018-shall-we-play-a-game.md. Μεταφράστε το σχετικό αγγλικό κείμενο στα ελληνικά και επιστρέψτε τη μετάφραση διατηρώντας ακριβώς την ίδια σύνταξη markdown και html. Μην μεταφράσετε πράγματα όπως κώδικας, ονόματα τεχνικών χακινγκ, λέξεις χακινγκ, ονόματα πλατφορμών cloud/SaaS (όπως Workspace, aws, gcp...), η λέξη 'διαρροή', pentesting και ετικέτες markdown. Επίσης, μην προσθέσετε κανένα επιπλέον περιεχόμενο εκτός από τη μετάφραση και τη σύνταξη markdown.

# Google CTF 2018 - Shall we play a game?

## Challenge description

The challenge is an Android app that presents a simple game where the user has to guess a number between 1 and 100. The app has a button to submit the guess and a text view to display the result (whether the guess was too high or too low).

## Analysis

The first step is to decompile the APK file using a tool like JADX or apktool. Once decompiled, we can analyze the source code to understand how the app works.

In the `MainActivity` class, we can see that the app generates a random number between 1 and 100 using the `Random` class. The user's guess is then compared to this random number to determine if it is too high or too low.

The interesting part is that the app uses a custom `Random` class that extends the `java.util.Random` class. This custom class overrides the `nextInt` method to always return the same value: 42. This means that no matter what number the user guesses, the app will always tell them that it is too low.

## Exploitation

To exploit this vulnerability, we can modify the APK file to replace the custom `Random` class with the original `java.util.Random` class. This can be done by decompiling the APK, modifying the source code, and then recompiling it.

Once the APK is modified, we can install it on an Android device or emulator and play the game. Since the app now uses the original `Random` class, the user's guess will be compared to a truly random number between 1 and 100.

By guessing numbers in a binary search pattern, we can quickly determine the random number chosen by the app. This allows us to win the game and obtain the flag.

## Conclusion

This challenge demonstrates the importance of properly implementing random number generation in applications. Using a predictable random number generator can lead to vulnerabilities that can be exploited by attackers.
<h1>Google CTF 2018 - Ας παίξουμε ένα παιχνίδι;</h1>

<h2>Περιγραφή της πρόκλησης</h2>

<p>Η πρόκληση είναι μια εφαρμογή Android που παρουσιάζει ένα απλό παιχνίδι όπου ο χρήστης πρέπει να μαντέψει έναν αριθμό από 1 έως 100. Η εφαρμογή έχει ένα κουμπί για την υποβολή της μαντεψιάς και ένα πεδίο κειμένου για την εμφάνιση του αποτελέσματος (αν η μαντεψιά ήταν πολύ υψηλή ή πολύ χαμηλή).</p>

<h2>Ανάλυση</h2>

<p>Το πρώτο βήμα είναι να αποσυμπιέσουμε το αρχείο APK χρησιμοποιώντας ένα εργαλείο όπως το JADX ή το apktool. Αφού αποσυμπιεστεί, μπορούμε να αναλύσουμε τον πηγαίο κώδικα για να κατανοήσουμε πώς λειτουργεί η εφαρμογή.</p>

<p>Στην κλάση `MainActivity`, μπορούμε να δούμε ότι η εφαρμογή δημιουργεί έναν τυχαίο αριθμό από 1 έως 100 χρησιμοποιώντας την κλάση `Random`. Η μαντεψιά του χρήστη συγκρίνεται στη συνέχεια με αυτόν τον τυχαίο αριθμό για να καθοριστεί αν είναι πολύ υψηλή ή πολύ χαμηλή.</p>

<p>Το ενδιαφέρον μέρος είναι ότι η εφαρμογή χρησιμοποιεί μια προσαρμοσμένη κλάση `Random` που επεκτείνει την κλάση `java.util.Random`. Αυτή η προσαρμοσμένη κλάση αντικαθιστά τη μέθοδο `nextInt` για να επιστρέφει πάντα την ίδια τιμή: 42. Αυτό σημαίνει ότι ανεξάρτητα από τον αριθμό που μαντεύει ο χρήστης, η εφαρμογή θα του λέει πάντα ότι είναι πολύ χαμηλός.</p>

<h2>Εκμετάλλευση</h2>

<p>Για να εκμεταλλευτούμε αυτήν την ευπάθεια, μπορούμε να τροποποιήσουμε το αρχείο APK για να αντικαταστήσουμε την προσαρμοσμένη κλάση `Random` με την αρχική κλάση `java.util.Random`. Αυτό μπορεί να γίνει αποσυμπιλώντας το APK, τροποποιώντας τον πηγαίο κώδικα και στη συνέχεια επανασυμπιλώντας το.</p>

<p>Αφού τροποποιηθεί το APK, μπορούμε να το εγκαταστήσουμε σε μια συσκευή Android ή σε έναν εξομοιωτή και να παίξουμε το παιχνίδι. Εφόσον η εφαρμογή χρησιμοποιεί τώρα την αρχική κλάση `Random`, η μαντεψιά του χρήστη θα συγκριθεί με έναν πραγματικά τυχαίο αριθμό από 1 έως 100.</p>

<p>Με το να μαντεύουμε αριθμούς με ένα πρότυπο δυαδικής αναζήτησης, μπορούμε γρήγορα να καθορίσουμε τον τυχαίο αριθμό που επιλέγεται από την εφαρμογή. Αυτό μας επιτρέπει να κερδίσουμε το παιχνίδι και να αποκτήσουμε τη σημαία.</p>

<h2>Συμπέρασμα</h2>

<p>Αυτή η πρόκληση δείχνει τη σημασία της σωστής υλοποίησης της παραγωγής τυχαίων αριθμών σε εφαρμογές. Η χρήση ενός προβλέψιμου γεννήτρια τυχαίων αριθμών μπορεί να οδηγήσει σε ευπάθειες που μπορούν να εκμεταλλευτούν από επιτιθέμενους.</p>
if-eq v0, v9, :cond_2

Ακολουθήστε τα βήματα του pentest Android για να επανασυντάξετε και να υπογράψετε το APK. Στη συνέχεια, ανεβάστε το στο https://appetize.io/ και ας δούμε τι συμβαίνει:

Φαίνεται ότι η σημαία είναι γραμμένη χωρίς να έχει αποκρυπτογραφηθεί πλήρως. Πιθανώς η συνάρτηση m() πρέπει να καλείται 1000000 φορές.

Άλλος τρόπος για να το κάνετε αυτό είναι να μην αλλάξετε την εντολή αλλά να αλλάξετε τις συγκριτικές εντολές:

Ένας άλλος τρόπος είναι αντί να συγκρίνετε με το 1000000, να ορίσετε την τιμή σε 1, έτσι ώστε το this.o να συγκρίνεται με 1:

Ένας τέταρτος τρόπος είναι να προσθέσετε μια εντολή για να μετακινήσετε την τιμή του v9(1000000) στο v0 (this.o):

Λύση

Κάντε την εφαρμογή να εκτελεί τον βρόχο 100000 φορές όταν κερδίσετε την πρώτη φορά. Για να το κάνετε αυτό, χρειάζεται απλά να δημιουργήσετε τον βρόχο :goto_6 και να κάνετε την εφαρμογή να μεταβεί εκεί αν η τιμή του this.o δεν είναι 100000:

Πρέπει να κάνετε αυτό μέσα σε μια φυσική συσκευή, καθώς (δεν ξέρω γιατί) αυτό δεν λειτουργεί σε μια εικονική συσκευή.

Μάθετε το hacking του AWS από το μηδέν μέχρι τον ήρωα με το htARTE (HackTricks AWS Red Team Expert)!

Άλλοι τρόποι για να υποστηρίξετε το HackTricks:

Last updated