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.
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 + '}')