Tags: reverse_engineering java
Rating:
This is quite easy given the availability of reversing tools online.
We are given a .class Java file. Looking up java class decompiler online gives this very useful tool.
I have previous experience with this platform, so I know choosing the second option will give very good outputs and it is usually fast.
public class Sekai {
private static int length = 6;
public static void main(String[] arrstring) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the flag: ");
String string = scanner.next();
if (string.length() != 43) {
System.out.println("Oops, wrong flag!");
return;
}
String string2 = string.substring(0, 6);
String string3 = string.substring(6, string.length() - 1);
String string4 = string.substring(string.length() - 1);
if (string2.equals("SEKAI{") && string4.equals("}")) {
assert (string3.length() == 6 * 6);
if (Sekai.solve((String)string3)) {
System.out.println("Congratulations, you got the flag!");
} else {
System.out.println("Oops, wrong flag!");
}
} else {
System.out.println("Oops, wrong flag!");
}
}
public static String encrypt(char[] arrc, int n) {
int n2;
char[] arrc2 = new char[12];
int n3 = 5;
int n4 = 6;
for (n2 = 0; n2 < 6 * 2; ++n2) {
arrc2[n2] = arrc[n3--];
arrc2[n2 + 1] = arrc[n4++];
++n2;
}
n2 = 0;
while (n2 < 6 * 2) {
int n5 = n2++;
arrc2[n5] = (char)(arrc2[n5] ^ (char)n);
}
return String.valueOf(arrc2);
}
public static char[] getArray(char[][] arrc, int n, int n2) {
int n3;
char[] arrc2 = new char[6 * 2];
int n4 = 0;
for (n3 = 0; n3 < 6; ++n3) {
arrc2[n4] = arrc[n][n3];
++n4;
}
for (n3 = 0; n3 < 6; ++n3) {
arrc2[n4] = arrc[n2][6 - 1 - n3];
++n4;
}
return arrc2;
}
public static char[][] transform(char[] arrc, int n) { // 36 letters to 6*6 grid
char[][] arrc2 = new char[n][n];
for (int i = 0; i < n * n; ++i) {
arrc2[i / n][i % n] = arrc[i];
}
return arrc2;
}
public static boolean solve(String string) {
char[][] arrc = Sekai.transform(string.toCharArray(), 6);
for (int i = 0; i <= 6 / 2; ++i) {
for (int j = 0; j < 6 - 2 * i - 1; ++j) {
char c = arrc[i][i + j];
arrc[i][i + j] = arrc[6 - 1 - i - j][i];
arrc[6 - 1 - i - j][i] = arrc[6 - 1 - i][6 - 1 - i - j];
arrc[6 - 1 - i][6 - 1 - i - j] = arrc[i + j][6 - 1 - i];
arrc[i + j][6 - 1 - i] = c;
}
}
return "oz]{R]3l]]B#50es6O4tL23Etr3c10_F4TD2".equals(
Sekai.encrypt(Sekai.getArray(arrc, 0, 5), 2) +
Sekai.encrypt(Sekai.getArray(arrc, 1, 4), 1) +
Sekai.encrypt(Sekai.getArray(arrc, 2, 3), 0);
}
}
Now it is just a basic crypto challenge.
My approach is accessible enough for beginners to Java like me: just use an online Java playground and print the intermediate output.
I used 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ as the flag body so the intermediate states will be unambiguous.
Here is an overview of what it does:
SEKAI{...} with 36 characters between the curly braces. (Sekai.main)1,4 and 2,3, Sekai.solve + Sekai.getArray)
The steps can be easily reversed even manually. I only used Python for the XOR step.