⭐Bugdroid Fight [2/2]
404CTF{4v4D0_K1dAvR0!}
Catégorie: Reverse Difficulté: medium Flag: -
Challenge
Description
Vous venez de consulter le message du Bugdroid...
Dans son message, il explique que le combat ne peut être gagné à la seule force des poings... À moins que vous ne soyez aidé d'une force divine : une formule magique se cache ici, elle vous permettra de gagner le duel.
Format de flag : 404CTF{formule_magique}
Décompilation
On a un fichier .aab
. Après quelques recherches, il est possible de générer un apk depuis celui-ci.
bundletool build-apks --bundle=Bugdroid_Fight_-_Part_2.aab --output=Bugdroid_Fight_-_Part_2.apks
Une fois l'archive créée, à l'intérieur se trouve universal.apk
, il faut alors la décompiler avec apktool (ou autre).
apktool d universal.apk
Résolution
On commence par une recherche globale dans les fichiers avec le mot "Bugdroid" (c'est le nom du challenge). Bingo, on trouve app_name
:
Searching 4652 files for "bugdroid" (whole word)
Bugdroid 2/resources.pb:
<binary>
Bugdroid 2/apk/resources/res/values/strings.xml:
32 <string name="alphabet">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890àé_{}</string>
33 <string name="androidx_startup">androidx.startup</string>
34: <string name="app_name">Bugdroid : 2e Combat</string>
35 <string name="appbar_scrolling_view_behavior">com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior</string>
36 <string name="bottom_sheet_behavior">com.google.android.material.bottomsheet.BottomSheetBehavior</string>
2 matches across 2 files
En se rendant dans strings.xml
, on observe une valeur un peu bizarre nommée action_header
<string name="action_header">!NFt8g7f_NOLtL</string>
<string name="action_settings">Settings</string>
<string name="alphabet">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890àé_{}</string>
<string name="androidx_startup">androidx.startup</string>
<string name="app_name">Bugdroid : 2e Combat</string>
Maintenant, on peut relancer une recherche avec action_header
:
Searching 4652 files for "action_header" (whole word)
...
Bugdroid 2/apk/sources/r0/C0428a.java:
43 Context i4 = homeFragment.i();
44 String valueOf = String.valueOf(textInputEditText.getText());
45: String string = homeFragment.G().getResources().getString(R.string.action_header);
46 c.n("getString(...)", string);
47 HashMap hashMap = new HashMap();
5 matches across 5 files
Le fichier r0/C0428a.java
semble intéressant puisqu'à l'intérieur, on trouve une comparaison entre deux strings qui affiche Correct
ou Incorrect
. Surement la vérification du mot de passe.
Les valeurs utilisées dans alphabet
, action_header
et edit
se trouvent dans strings.xml
Si l'on regarde les lignes au-dessus (j'ai supprimé les lignes inutiles et commenté) :
HomeFragment homeFragment = (HomeFragment) obj2;
TextInputEditText textInputEditText = (TextInputEditText) obj;
int i3 = HomeFragment.f2487W;
c.o("this$0", homeFragment);
c.o("$textInput", textInputEditText);
Context i4 = homeFragment.i();
// notre input de mot de passe
String password = String.valueOf(textInputEditText.getText());
// map de conversion de caractères
HashMap hashMap = new HashMap();
// !NFt8g7f_NOLtL
String action_header = homeFragment.G().getResources().getString(R.string.action_header);
// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890àé_{}
String alphabet = homeFragment.G().getResources().getString(R.string.alphabet);
// 8qROIjDcr1fdXUSAkFH5hà9QToé3xg6eKnVlmu2zpCb4GJEtiwWy70vLPsYBaNZM_{}
String edit = homeFragment.G().getResources().getString(R.string.edit);
int i = 0;
while (i < alphabet.length() && i < edit.length()) {
// Associe à chaque caractère de alphabet, le caractère à la même position dans edit
hashMap.put(Character.valueOf(alphabet.charAt(i)), Character.valueOf(edit.charAt(i)));
i++;
}
StringBuilder encrypted = new StringBuilder();
// En commençant par la fin du mot de passe, le transforme selon la map de conversion
for (int length = password.length() - 1; -1 < length; length--) {
char charAt = password.charAt(length);
// Ajoute le caractère converti à encrypted
encrypted.append(((Character) hashMap.getOrDefault(Character.valueOf(charAt), Character.valueOf(charAt))).charValue());
}
if (c.f(encrypted.toString(), action_header)) message = "Correct!";
else message = "Incorrect!";
Toast.makeText(i4, message, 0).show();
Il suffit donc d'inverser le chiffrement depuis le résultat attendu.
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890àé_{}'
edit = '8qROIjDcr1fdXUSAkFH5hà9QToé3xg6eKnVlmu2zpCb4GJEtiwWy70vLPsYBaNZM_{}'
action_header = '!NFt8g7f_NOLtL'
password = ''
for c in action_header[::-1]:
if c in edit:
password += alphabet[edit.index(c)]
else:
password += c
print('404CTF{' + password + '}')
Mis à jour
Ce contenu vous a-t-il été utile ?