Methods
For this challenge, probably we need install some things into our Android 5.1 device with Genymotion.
For example, an ARM Translator.
https://github.com/m9rco/Genymotion_ARM_Translation
For download the APK
https://team-sik.org/wp-content/uploads/2017/06/FlagValidator.apk_.zip
With apktool will extract the content of the apk file
apktool d FlagValidator.apk
Let’s see the content of MainActivity.java that say so clear the structure of the flag.
In the onValidateClick method
public void onValidateClick(View view) {
new StringBuilder("Validate Token input: ").append((Object) this.input.getText());
String[] split = this.input.getText().toString().split("-");
if (split.length != 4) {
Toast.makeText(this, "Wrong token format, don't forget - between xxx !", 1).show();
} else {
a.a(split[0]);
a.b(split[1]);
a.c(split[2]);
a.d(split[3]);
}
new StringBuilder("Subparts ").append(m.cardinality());
if (m.cardinality() != 4) {
Toast.makeText(this, "Still " + (4 - m.cardinality()) + " token missing !", 1).show();
return;
}
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(split[0]);
stringBuffer.append("-");
stringBuffer.append(split[1]);
stringBuffer.append("-");
stringBuffer.append(split[2]);
stringBuffer.append("-");
stringBuffer.append(split[3]);
new StringBuilder("Flag combined ").append(stringBuffer.toString());
if ("1017e4fefe8381aec8c3fbaf8f8148f53f81d340".equals(org.team_sik.flagvalidator.a.a.a.a.a(stringBuffer.toString(), "SHA1"))) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Congratulation !").setCancelable(false).setPositiveButton("Yeah", new DialogInterface.OnClickListener() { // from class: org.team_sik.flagvalidator.MainActivity.1
@Override // android.content.DialogInterface.OnClickListener
public final void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.create().show();
}
}
For every part we have a different method
Here is the four methods in org.team_sik.flagvalidator.a.a.b
public static void a(String str) {
if ("cHVtcjRX".equals(org.team_sik.flagvalidator.a.a.a.a.a(str))) {
MainActivity.m.set(1, true);
} else {
MainActivity.m.set(1, false);
}
}
public static void b(String str) {
if (org.team_sik.flagvalidator.a.a.a.a.a(a).equals(str)) {
MainActivity.m.set(2, true);
} else {
MainActivity.m.set(2, false);
}
}
public static void c(String str) {
try {
Field declaredField = Class.forName(org.team_sik.flagvalidator.a.a.a.a.a(new int[]{1879986099, 1260141997, 1879986140, 1260142047, -885815433, -256489066, 1879986119, 1260142024, -885815439, -256489003, 1879986156, 1260142046, -885815431, -256489005, 1879986077, 1260142027, -885815428, -256488999, 1879986132, 1260142043, -885815439, -256489004, 1879986138, 1260142025, -885815439, -256489012, 1879986140, 1260142047, -885815490, -256488971, 1879986130, 1260142020, -885815426, -256488967, 1879986128, 1260142041, -885815431, -256489010, 1879986138, 1260142041, -885815447, -885815536, -256489032})).getDeclaredField("TOKEN2");
declaredField.setAccessible(true);
new StringBuilder("Flag value ").append((String) declaredField.get(new MainActivity()));
if (((String) declaredField.get(new MainActivity())).equals(str)) {
MainActivity.m.set(3, true);
} else {
MainActivity.m.set(3, false);
}
} catch (ClassNotFoundException e) {
Log.e("VAL", "Something went wrong :-(");
} catch (IllegalAccessException e2) {
Log.e("VAL", "Something went wrong :-(");
} catch (NoSuchFieldException e3) {
Log.e("VAL", "Something went wrong :-(");
}
}
public static void d(String str) {
if ("af246d4dacd2f683ff850dcfe465562f".equals(org.team_sik.flagvalidator.a.a.a.a.a(str, "MD5"))) {
MainActivity.m.set(4, true);
} else {
MainActivity.m.set(4, false);
}
}
Method 1
public static void a(String str) {
if ("cHVtcjRX".equals(org.team_sik.flagvalidator.a.a.a.a.a(str))) {
MainActivity.m.set(1, true);
} else {
MainActivity.m.set(1, false);
}
}
We have the string cHVtcjRX
That have this logic
public static String a(String str) {
String sb = new StringBuilder(str).reverse().toString();
String str2 = "";
try {
str2 = Base64.encodeToString(sb.getBytes("utf-8"), 2);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return str2;
}
This about an base64 encode and reversed.
echo 'cHVtcjRX' | base64 -d | rev
Output: W4rmup
Method 2
public static void b(String str) {
if (org.team_sik.flagvalidator.a.a.a.a.a(a).equals(str)) {
MainActivity.m.set(2, true);
} else {
MainActivity.m.set(2, false);
}
}
And this is the logic
public static String a(int[] iArr) {
StringBuilder sb = new StringBuilder();
int i = iArr[0];
int i2 = iArr[1];
int i3 = iArr[iArr.length - 2];
int i4 = iArr[iArr.length - 1];
for (int i5 = 2; i5 < iArr.length - 2; i5++) {
sb.append((char) (iArr[i5] ^ new int[]{i, i2, i3, i4}[(i5 - 2) % 4]));
}
return sb.toString();
}
There are another value of a which is
private static final int[] a = {-1602723372, 811074983, -1602723401, 811075023, -949198329, 1053776347, -1602723400, 811074964, -949198243, 1053776336, -1602723353, -949198285, 1053776311};
This is a simple logic in java working with array. We can do an python script that do the same job an get a fast output
#!/usr/bin/env python3
def a(iArr):
sb = []
i = iArr[0]
i2 = iArr[1]
i3 = iArr[-2]
i4 = iArr[-1]
for i5 in range(2, len(iArr) - 2):
decoded_char = chr(iArr[i5] ^ [i, i2, i3, i4][(i5 - 2) % 4])
sb.append(decoded_char)
return ''.join(sb)
iArr = [-1602723372, 811074983, -1602723401, 811075023, -949198329, 1053776347,
-1602723400, 811074964, -949198243, 1053776336, -1602723353, -949198285, 1053776311]
final = a(iArr)
print(final)
Output: ch4ll3ng3
Method 3
public static void c(String str) {
try {
Field declaredField = Class.forName(org.team_sik.flagvalidator.a.a.a.a.a(new int[]{1879986099, 1260141997, 1879986140, 1260142047, -885815433, -256489066, 1879986119, 1260142024, -885815439, -256489003, 1879986156, 1260142046, -885815431, -256489005, 1879986077, 1260142027, -885815428, -256488999, 1879986132, 1260142043, -885815439, -256489004, 1879986138, 1260142025, -885815439, -256489012, 1879986140, 1260142047, -885815490, -256488971, 1879986130, 1260142020, -885815426, -256488967, 1879986128, 1260142041, -885815431, -256489010, 1879986138, 1260142041, -885815447, -885815536, -256489032})).getDeclaredField("TOKEN2");
declaredField.setAccessible(true);
new StringBuilder("Flag value ").append((String) declaredField.get(new MainActivity()));
if (((String) declaredField.get(new MainActivity())).equals(str)) {
MainActivity.m.set(3, true);
} else {
MainActivity.m.set(3, false);
}
} catch (ClassNotFoundException e) {
Log.e("VAL", "Something went wrong :-(");
} catch (IllegalAccessException e2) {
Log.e("VAL", "Something went wrong :-(");
} catch (NoSuchFieldException e3) {
Log.e("VAL", "Something went wrong :-(");
}
}
In the MainActivity.java we can see TOKEN2
public class MainActivity extends d {
public static BitSet m;
private String TAG = getClass().getSimpleName();
private String TOKEN2 = value();
private EditText input;
static {
System.loadLibrary("native-lib");
m = new BitSet(4);
}
And value() is
public native String value();
An string of the native libraries.
Let’s use ghidra for see the libraries and what we can found inside.
I’ll use this .so file
FlagValidator/lib
└── x86
└── libnative-lib.so
The third flag is 5UcC33D3d
Method 4
public static void d(String str) {
if ("af246d4dacd2f683ff850dcfe465562f".equals(org.team_sik.flagvalidator.a.a.a.a.a(str, "MD5"))) {
MainActivity.m.set(4, true);
} else {
MainActivity.m.set(4, false);
}
}
This MD5 is so broke.
You can find in crackstation the string according to the MD5 value
Value: continue1
Then the final flag looks like
W4rmup-ch4ll3ng3-5UcC33D3d-continue1
Just insert in the text box and
I hope you found it useful (:
Leave a Reply