Summary
In this challenge, you are provided with the file shuff.apk. The goal of this challenge is to find a valid flag string that works when entered into the application. My analysis using the JADX GUI shows that the application does not use obfuscation or complex encryption; instead, it statically reconstructs the flag string in memory using array index mapping.
Vulnerability Analysis
The vulnerability in this app lies in the storage of sensitive data and the flag reconstruction logic, which are exposed transparently without any protection.
Here is what I found in the APK’s source code:
<com.apeka.hexshuffle.MainActivity>(Input Validation Points)
String candidate = input.getText().toString().trim();
result.setVisibility(0);
if (TextUtils.isEmpty(candidate)) {
result.setTextColor(-6381922);
result.setText("Enter something!");
} else if (candidate.equals(SecretData.recover())) {
result.setTextColor(-13730510);
result.setText("Correct! Nice reversing.");
} else {
result.setTextColor(-3790808);
result.setText("Nope, keep digging.");
- <com.apeka.hexshuffle.SecretData>(Flag Reconstruction Logic)
public final class SecretData {
static final String[] ASCII = {"r", "4", "t", "n", "_", "s", "a", "_", "4", "1", "0", "1", "d", "n", "0", "r", "t", "c", "_", "k", "t", "p", "_", "n", "3", "3", "u", "0", "v"};
private SecretData() {
}
public static String recover() {
StringBuilder sb = new StringBuilder();
for (int i : IndexMap.ORDER) {
sb.append(ASCII[i]);
}
return "JCC{" + ((Object) sb) + "}";
}
}
- <com.apeka.hexshuffle.IndexMap>(Static Index Map)
public final class IndexMap {
static final int[] ORDER = {1, 13, 7, 11, 23, 20, 15, 14, 12, 26, 17, 2, 9, 27, 3, 4, 16, 10, 22, 8, 21, 24, 19, 6, 18, 0, 25, 28, 5};
private IndexMap() {
}
}
Since all the data and the flag-generation process are transparently stored in the source code, the flag can be reconstructed directly without needing to run the Android app on an Android emulator. The logic behind this process is fully replicated using this script.
# Data from decompilation
ASCII = [
"r", "4", "t", "n", "_", "s", "a", "_", "4", "1", "0", "1", "d", "n", "0", "r", "t", "c", "_", "k", "t", "p", "_", "n", "3", "3", "u", "0", "v"
]
ORDER = [
1, 13, 7, 11, 23, 20, 15, 14, 12, 26, 17, 2, 9, 27, 3, 4, 16, 10, 22, 8, 21, 24, 19, 6, 18, 0, 25, 28, 5
]
# Flag reconstruction
# Retrieve characters in the ORDER sequence
inner = ''.join(ASCII[i] for i in ORDER)
# Wrap it in the flag shape
flag = "JCC{" + inner + "}"
print("Flag reconstruction:", flag)
FLAG: JCC{4n_1ntr0duct10n_t0_4p3ka_r3vs}